// tr1::tuple #include <tuple> using std::tr1::tuple; tuple<> none; // holds no elements tuple<int> one; // holds one element, of type int int i; double d; tuple<int&, const double&> two(i, d); // holds two elements, one of // type reference to int and one // of type reference to const double tuple<int, int, int, int, int, int, int, int, int, int> ten; // holds ten elements, all of type int // implementation dependent upper limit: N==10 // // get returns a reference to an element (may be modified) // tuple_size, tuple_element // create tuple #include <utility> #include <tuple> using std::tr1::tuple; using std::pair; class C { public: C() : val(0) {} C(int i) : val(i) {} private: int val; }; tuple<> t0; // default constructor tuple<int> t1; // default constructor; element // not initialized tuple<int> t2(3); // element initialized to 3 tuple<C> t3; // element initialized to C() tuple<C> t4(C(1)); // element initialized to C(1) tuple<C, C> t5(1, 2); // first element initialized to C(1) // second element initialized to C(2) tuple<double> t6(t2); // element initialized to 3.0 pair<int, int> p0(3, 4); // first element initialized to 3 // second element initialized to 4 tuple<C, C> t7(p0); // first element initialized to C(3) // second element initialized to C(4) // make_tuple #include <tuple> #include <typeinfo> #include <iostream> using std::tr1::tuple; using std::tr1::make_tuple; template <class T> void show_type(T) { std::cout << typeid(T).name() << "\n\n"; } int main() { int i = 3; int& j = i; show_type(make_tuple()); // returns tuple<> show_type(make_tuple(1, 3.14)); // returns tuple<int,double> show_type(make_tuple(i, j)); // returns tuple<int,int> return 0; } // make_tuple() does not distinguish between ref and value // for references use tr1::functional #include <tuple> #include <functional> // for ref, cref using std::tr1::make_tuple; using std::tr1::ref; using std::tr1::cref; void test() { int i = 17; int j = 3; make_tuple(ref(i),cref(j)); // returns tuple<int&, const int&> // first element is reference to i // second element is reference to j } // tie returns a tupple with references // ignore tells not to use operator=() #include <tuple> #include <iostream> using std::tr1::make_tuple; using std::tr1::tie; using std::tr1::ignore; int i = 1; int j = 2; int k = 3; void show() { std::cout << i << ' ' << j << ' ' << k << '\n'; } int main() { show(); // 1 2 3 tie(i, ignore, k) = make_tuple(5, 6, 7); show(); // 5 2 7 return 0; } // assignment: the number of elements must be the same // the fields must be convertible #include <utility> #include <iostream> #include <tuple> using std::tr1::tuple; using std::tr1::get; using std::cout; using std::make_pair; void show(int i, int j, const tuple<int,int&,int>& t) { cout << i << ' ' << j << ": " << get<0>(t) << ' ' << get<1>(t) << ' ' << get<2>(t) << '\n'; } void show(const tuple<int,int>& t) { cout << get<0>(t) << ' ' << get<1>(t) << '\n'; } int main() { int i = 1, j = 2; tuple<int,int&,int> t0(i, j, 3); tuple<int,double,char> t1(4, 5.1, '\6'); show(i, j, t0); // 1 2: 1 2 3 t0 = t1; show(i, j, t0); // 1 5: 4 5 6 tuple<int,int> t2(1, 2); show(t2); // 1 2 t2 = make_pair(3, 4); show(t2); // 3 4 return 0; } // get access a field [ 0 .. N-1 ] #include <tuple> #include <iostream> using std::tr1::tuple; using std::tr1::get; using std::cout; int main() { tuple<int,int> t0(1, 2); cout << get<0>(t0) << ' ' << get<1>(t0) << '\n'; // 1 2 return 0; } // returning a reference, can be used to modified field: #include <tuple> #include <iostream> using std::tr1::tuple; using std::tr1::get; using std::cout; void show(int i, int j, const tuple<int,int&,int> t) { cout << i << ' ' << j << ": " << get<0>(t) << ' ' << get<1>(t) << ' ' << get<2>(t) << '\n'; } int main() { int i = 1, j = 2; tuple<int,int&,int> t0(i, j, 3); show(i, j, t0); // 1 2: 1 2 3 get<0>(t0) = 4; // set first element to 4 get<1>(t0) = 5.1; // set object referred to by // second element to 5 get<2>(t0) = '\6'; // set third element to 6 show(i, j, t0); // 1 5: 4 5 6 return 0; } // access in compile time #include <tuple> #include <iostream> using std::tr1::tuple; using std::tr1::tuple_size; using std::cout; typedef tuple<> tuple0; typedef tuple<int> tuple1; typedef tuple<int&,double&> tuple2; typedef tuple<int,int,int,int,int> tuple5; int main() { cout << tuple_size<tuple0>::value << '\n'; // 0 cout << tuple_size<tuple1>::value << '\n'; // 1 cout << tuple_size<tuple2>::value << '\n'; // 2 cout << tuple_size<tuple5>::value << '\n'; // 5 return 0; } // type_element is defined by typedef: template <int Idx, class Tuple> struct tuple_element { typedef ... type; }; #include <tuple> #include <iostream> #include <typeinfo> using std::tr1::tuple; using std::tr1::tuple_element; using std::cout; typedef tuple<int> tuple1; typedef tuple<int&,double&> tuple2; template <class Ty> void show_type() { cout << typeid(Ty).name() << '\n'; }; int main() { show_type<tuple_element<0, tuple1>::type>(); // int show_type<tuple_element<0, tuple2>::type>(); // int show_type<tuple_element<1, tuple2>::type>(); // double return 0; } // Comparison // Two tuple object can be compared if they have // the same number of elements. // == != < <= > >= // lexicographical + shortcut // for == and != member == is used // for < <= > >= member < is used tuple<int, double, int> first(0,2.0,1); tuple<long,float,int> second(0,1.0,2); first < second (1) get<0>(first) < get<0>(second) false (2) get<0>(second) < get<0>(first) false (3) get<1>(first) < get<1>(second) false (4) get<1>(second) < get<1>(first) true first < second false #include <iostream> #include <iomanip> #include <tuple> using std::tr1::tuple; using std::cout; using std::boolalpha; class C { public: C(int i) : val(i) {} int value() const {return val;} private: int val; }; bool operator==(const C& left, const C& right) { bool res = left.value() == right.value(); cout << " " << left.value() << " == " << right.value(); cout << " is " << res << '\n'; return res; } bool operator<(const C& left, const C& right) { bool res = left.value() < right.value(); cout << " " << left.value() << " < " << right.value(); cout << " is " << res << '\n'; return res; } #define TEST(expr) \ cout << #expr << '\n'; \ cout << " result is " << (expr) << '\n' typedef tuple<C&,C&,C&> tuple1; int main() { C a = 1; C b = 2; C c = 3; C d = 1; C e = 4; C f = 3; cout << boolalpha; // set alphabetic form for bool tuple1 t0(a, b, c); tuple1 t1(d, e, f); TEST(t0 == t1); // a == d is true, b == e is false, // result is false TEST(t0 != t1); // t0 == t1 is false, result is true TEST(t0 < t1); // a < d is false, // d < a is false and b < e is true, // result is true TEST(t1 <= t0); // t0 < t1 is true, result is false TEST(t1 > t0); // t0 < t1 is true, result is true TEST(t0 >= t1); // t0 < t1 is true, result is false return 0; } // same extension to pair<T1,T2>