2010-02-05 12:25:42 +01:00
|
|
|
The C++0x standard offers a emi(generalized pair) container: the emi(tuple),
|
2010-05-06 16:19:22 +02:00
|
|
|
covered in this section. Before tuples can be used the header file
|
|
|
|
tthi(tuple) must have been included.
|
|
|
|
|
|
|
|
Whereas tt(std::pair) containers have limited functionality and only support
|
|
|
|
two members, tuples have slightly more functionality and may contain an
|
|
|
|
unlimited number of different data types. In that respect a tuple can be
|
|
|
|
thought of the `template's answer to bf(C)'s struct'.
|
2009-07-06 16:38:05 +02:00
|
|
|
|
2010-02-05 12:25:42 +01:00
|
|
|
A tuple's generic declaration (and definition) uses the variadic template
|
2010-02-28 17:34:35 +01:00
|
|
|
notation:
|
2009-07-06 16:38:05 +02:00
|
|
|
verb(
|
2010-02-28 17:34:35 +01:00
|
|
|
template <class ...Types>
|
2010-02-05 12:25:42 +01:00
|
|
|
class tuple;
|
2009-07-06 16:38:05 +02:00
|
|
|
)
|
2010-02-05 12:25:42 +01:00
|
|
|
Here is an example of its use:
|
2009-07-06 16:38:05 +02:00
|
|
|
verb(
|
|
|
|
typedef std::tuple<int, double &, std::string, char const *> tuple_idsc;
|
2009-07-15 13:58:17 +02:00
|
|
|
|
2009-07-06 16:38:05 +02:00
|
|
|
double pi = 3.14;
|
|
|
|
tuple_idsc idsc(59, pi, "hello", "fixed");
|
2009-07-15 13:58:17 +02:00
|
|
|
|
2009-07-06 16:38:05 +02:00
|
|
|
// access a field:
|
|
|
|
std::get<2>(idsc) = "hello world";
|
2009-07-15 13:58:17 +02:00
|
|
|
)
|
2010-02-05 12:25:42 +01:00
|
|
|
The hi(get)tt(std::get<idx>(tupleObject)) function template returns a
|
2011-01-05 16:14:00 +01:00
|
|
|
reference to the tt(idx)+sups(th) field of the tuple tt(tupleObject). Index 0
|
2010-02-05 12:25:42 +01:00
|
|
|
returns a reference to its first value. The index is specified as the function
|
|
|
|
template's non-type template argument.
|
2009-07-15 13:58:17 +02:00
|
|
|
|
2010-02-05 12:25:42 +01:00
|
|
|
Tuples may be constructed without specifying initial values. Primitive
|
|
|
|
types are initialized to zeroes; class type fields are initialized by their
|
|
|
|
default constructors. Be aware that in some situations the construction of a
|
|
|
|
tuple may succeed but its use may fail. Consider:
|
2009-07-06 16:38:05 +02:00
|
|
|
verb(
|
|
|
|
tuple<int &> empty;
|
|
|
|
cout << get<0>(empty);
|
|
|
|
)
|
2010-02-05 12:25:42 +01:00
|
|
|
Here the tuple tt(empty) cannot be used as its tt(int &) field is an
|
|
|
|
undefined reference. tt(Empty)'s construction, however, succeeds.
|
2009-07-06 16:38:05 +02:00
|
|
|
|
2010-02-05 12:25:42 +01:00
|
|
|
Tuples may be assigned to each other if their type lists are identical; if
|
|
|
|
supported by their constituent types copy constructors are available as
|
|
|
|
well. Copy construction and assignment is also available if a right-hand type
|
|
|
|
can be converted to its matching left-hand type or if the left-hand type can
|
|
|
|
be constructed from the matching right-hand type. Tuples
|
|
|
|
(matching in number and (convertible) types) can be compared using relational
|
|
|
|
operators as long as their constituent types support comparisons. In this
|
|
|
|
respect tuples are like pairs.
|
2009-07-06 16:38:05 +02:00
|
|
|
|
2010-02-05 12:25:42 +01:00
|
|
|
Tuples offer the following static elements (using compile-time
|
|
|
|
initialization):
|
2009-07-06 16:38:05 +02:00
|
|
|
itemization(
|
2010-02-05 12:25:42 +01:00
|
|
|
itht(tuple_size)(std::tuple_size<Tuple>::value) returns the number of
|
|
|
|
types defined for the tuple type tt(Tuple). Example:
|
2009-07-06 16:38:05 +02:00
|
|
|
verb(
|
2010-02-05 12:25:42 +01:00
|
|
|
cout << tuple_size<tuple_idsc>::value << '\n'; // displays: 4
|
2009-07-06 16:38:05 +02:00
|
|
|
)
|
2011-01-27 11:04:08 +01:00
|
|
|
itht(tuple_element)(std::tuple_element<idx, Tuple>::type)
|
2010-02-05 12:25:42 +01:00
|
|
|
returns the type of element tt(idx) of tt(Tuple). Example:
|
2009-07-06 16:38:05 +02:00
|
|
|
verb(
|
2010-02-05 12:25:42 +01:00
|
|
|
tuple_element<2, tuple_idsc>::type text; // defines std::string text
|
2009-07-06 16:38:05 +02:00
|
|
|
)
|
|
|
|
)
|
2010-02-05 12:25:42 +01:00
|
|
|
|
|
|
|
The unpack operator can also be used to forward the arguments of a
|
|
|
|
constructor to a tuple data member. Consider a class tt(Wrapper) that is
|
|
|
|
defined as a variadic template:
|
|
|
|
verb(
|
|
|
|
template <typename ... Params>
|
|
|
|
class Wrapper
|
|
|
|
{
|
|
|
|
...
|
|
|
|
public:
|
2011-03-01 11:08:08 +01:00
|
|
|
Wrapper(Params &&...params);
|
2010-02-05 12:25:42 +01:00
|
|
|
};
|
|
|
|
)
|
|
|
|
This class may be given a tuple data member which should be initialized by
|
|
|
|
the types and values that are used when initializing an object of the class
|
|
|
|
hi(perfect forwarding: to data members) tt(Wrapper) using perfect
|
|
|
|
forwarding. Comparable to the way a class may inherit from its template types
|
|
|
|
(cf. section ref(UNPACK)) it may forward its types and constructor arguments
|
|
|
|
to its tuple data member:
|
|
|
|
verb(
|
|
|
|
template <typename ... Params>
|
|
|
|
class Wrapper
|
|
|
|
{
|
|
|
|
std::tuple<Params ...> d_tuple; // same types as used for
|
|
|
|
// Wrapper itself
|
|
|
|
public:
|
2011-03-01 11:08:08 +01:00
|
|
|
Wrapper(Params &&...params)
|
2010-02-05 12:25:42 +01:00
|
|
|
: // initialize d_tuple with
|
|
|
|
// Wrapper's arguments
|
|
|
|
d_tuple(std::forward<Params>(params) ...)
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
)
|