1 概述
元组(tuple)是将不同类型的元素打包在一个对象中的对象,就像对对象对元素对所做的那样,但对任何数量的元素都是通用的。
从概念上讲,它们类似于普通的旧数据结构(类C结构),但没有命名的数据成员,而是按元组中的顺序访问其元素。
元组中特定元素的选择是在模板实例化级别完成的,因此,它必须在编译时使用get和tie等辅助函数进行指定。
元组类与pair类密切相关:元组可以由对构建,出于某些目的,pair 可以被视为元组。
数组(array)容器还具有某些类似元组(tuple)的功能。
其类图如下:

2 使用实例
void TupleSuite::get()
{
std::tuple<int , char> a(10, 'a');
std::get<0>(a) = 20;
std::tuple_element<0, decltype(a)>::type b = std::get<0>(a);//b is int
TEST_ASSERT_EQUALS(20, b)
TEST_ASSERT_EQUALS('a', std::get<1>(a))
TEST_ASSERT_EQUALS('b', std::get<1>(std::tuple<int , char>(10, 'b')))
}
3 接口使用
3.1 constructor
void TupleSuite::constructor()
{
std::tuple<int,char> a; // default
std::tuple<int,char> b (a); // copy
std::tuple<int,char> c (std::make_tuple(20,'b')); // move
std::tuple<long,char> d (c); // implicit conversion
std::tuple<int,char, char> e (10,'a', 'b'); // initialization
std::tuple<int,char> f (std::make_pair(30,'c')); // from pair / move
TEST_ASSERT_EQUALS(2, std::tuple_size<decltype(a)>::value)
TEST_ASSERT_EQUALS(2, std::tuple_size<decltype(b)>::value)
TEST_ASSERT_EQUALS(2, std::tuple_size<decltype(c)>::value)
TEST_ASSERT_EQUALS(2, std::tuple_size<decltype(d)>::value)
TEST_ASSERT_EQUALS(3, std::tuple_size<decltype(e)>::value)
TEST_ASSERT_EQUALS(2, std::tuple_size<decltype(f)>::value)
}
3.2 get
void TupleSuite::get()
{
std::tuple<int , char> a(10, 'a');
std::get<0>(a) = 20;
TEST_ASSERT_EQUALS(20, std::get<0>(a))
TEST_ASSERT_EQUALS('a', std::get<1>(a))
TEST_ASSERT_EQUALS('b', std::get<1>(std::tuple<int , char>(10, 'b')))
}
说明:
- get函数越界后,会有参数列表匹配错误,导致编译出错。
3.3 assigns
void TupleSuite::assigns()
{
std::pair<int, char> pair(10, 'a');
std::tuple<int, char> a(20, 'b');
std::tuple<int, char> b;
std::tuple<long, char> c;
std::tuple<long, char, char> d;
b = a; //copy assignment
TEST_ASSERT_EQUALS('b', std::get<1>(b))
c = std::make_tuple(30L, 'c');//move assignment
TEST_ASSERT_EQUALS('c', std::get<1>(c))
a = c;//conversion assignment
TEST_ASSERT_EQUALS(30, std::get<0>(a))
c = std::make_tuple(30, 'd');//conversion / move assignment
TEST_ASSERT_EQUALS('d', std::get<1>(c))
c = pair;//from pair assignment
TEST_ASSERT_EQUALS('a', std::get<1>(c))
a = std::make_pair(2, 'b');//form pair /move assignment
TEST_ASSERT_EQUALS('b', std::get<1>(a))
}
3.4 swap
void TupleSuite::swap()
{
std::tuple<int,char> a (10,'x');
std::tuple<int,char> b (20,'y');
TEST_ASSERT_EQUALS(10, std::get<0>(a))
TEST_ASSERT_EQUALS('x', std::get<1>(a))
TEST_ASSERT_EQUALS(20, std::get<0>(b))
TEST_ASSERT_EQUALS('y', std::get<1>(b))
a.swap(b);
TEST_ASSERT_EQUALS(20, std::get<0>(a))
TEST_ASSERT_EQUALS('y', std::get<1>(a))
TEST_ASSERT_EQUALS(10, std::get<0>(b))
TEST_ASSERT_EQUALS('x', std::get<1>(b))
std::swap(a, b);
TEST_ASSERT_EQUALS(10, std::get<0>(a))
TEST_ASSERT_EQUALS('x', std::get<1>(a))
TEST_ASSERT_EQUALS(20, std::get<0>(b))
TEST_ASSERT_EQUALS('y', std::get<1>(b))
}
3.4 relational
void TupleSuite::relational()
{
std::tuple<int,char> a (10,'x');
std::tuple<char,char> b (10,'x');
std::tuple<char,char> c (10,'y');
TEST_ASSERT_EQUALS(true, a == b)
TEST_ASSERT_EQUALS(true, b != c)
TEST_ASSERT_EQUALS(true, b < c)
TEST_ASSERT_EQUALS(true, c > a)
TEST_ASSERT_EQUALS(true, a <= c)
TEST_ASSERT_EQUALS(true, c >= b)
TEST_ASSERT_EQUALS(true, a >= b)
TEST_ASSERT_EQUALS(true, b >= a)
}
3.4 cat
void TupleSuite::cat()
{
std::tuple<float, std::string> a(3.14, "pi");
std::tuple<int, char> b(10, 'a');
auto c = std::tuple_cat(a, b);
TEST_ASSERT_EQUALS(4, std::tuple_size<decltype(c)>::value)
TEST_ASSERT_EQUALS(3.14f, std::get<0>(c))//3.14
TEST_ASSERT_EQUALS("pi", std::get<1>(c))
TEST_ASSERT_EQUALS(10, std::get<2>(c))
TEST_ASSERT_EQUALS('a', std::get<3>(c))
}
3.4 tie
void TupleSuite::tie()
{
std::tuple<int, float, char> a = std::make_tuple(10, 2.6, 'a');
int i;
char c;
std::tie(i, std::ignore, c) = a;
TEST_ASSERT_EQUALS(10, i)
TEST_ASSERT_EQUALS('a', c)
}
3.4 forward
void TupleSuite::forward()
{
auto a = std::make_tuple(10, 'a');
auto b = std::forward_as_tuple(10, 'a');
std::tuple<int, char> c;
std::tuple<int &&, char &&> d(20, 'a');
std::get<0>(a) = 20;
std::get<0>(b) = 30;
TEST_ASSERT_EQUALS(false, typeid(a) == typeid(b))
TEST_ASSERT_EQUALS(true, typeid(a) == typeid(c))
TEST_ASSERT_EQUALS(true, typeid(b) == typeid(d))
TEST_ASSERT_EQUALS(20, std::get<0>(a))
TEST_ASSERT_EQUALS(30, std::get<0>(b))
}
说明:
- make_tuple构造tuple<int, char>类型tuple
- forward_as_tuple构造tuple<int&&, char&&>类型tuple
1104

被折叠的 条评论
为什么被折叠?



