// 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>