《C++ Primer》 17.1 tuple类型(P636)
tuple是一种定义在标准库中的类似于pair的模板。pair的成员为两个不同的类型,tuple同样要求成员类型不同,但是tuple可以有任意数量的成员。
定义一个tuple对象时,可以使用默认的构造函数,它会为每个成员进行默认初始化。当然也可以手动初始化。
tuple tp1;//使用默认构造进行初始化
tuple tp2{ 1, "hello", 2 };//自定义直接初始化
tuple tp3 = { 1, "hello", 2 };//错误,并非直接初始化
值得注意的是,《C++ Primer》说“tuple的构造函数是explicit,因此必须使用直接初始化”,因此tp3应该编译失败。但是在VS2019环境实测中,编译是正常通过的,应该是VS对tuple类型进行了优化,支持了隐式类型转换。
类似make_pair函数,标准库定义了make_tuple函数来生成tuple对象:
auto tp4 = make_tuple(1, "hello", 2);
auto tp5 = make_tuple(1, "hello", 2);
需要说明的是,如果没有为make_tuple指明变量类型, 例如“hello”就会默认是const char*类型。
访问tuple成员时,需要使用名为get的标准库函数模板,用法如下:
auto tp1 = make_tuple(1, "hello", 2);
int a = get<0>(tp1);
string str = get<1>(tp1);
int b = get<2>(tp1);
当我们访问tuple成员时,从0开始计数,因此get<0>的含义是tuple的第一个成员。
get函数所返回的是成员的引用。
获取未知tuple对象的类型:
auto tp1 = make_tuple(1, "hello", 2);
typedef decltype(tp1) TUPLE_TYPE;//使用decltype来获取tp1的类型
TUPLE_TYPE tp2;
//获取tp1的类型,定义别名为TUPLE_TYPE,来定义对象tp2。
获取tuple中成员总数:
size_t sz = tuple_size::value;
获取tuple某个具体成员的类型:
tuple_element<0, TUPLE_TYPE>::type a = get<0>(tp1);
//a类型为int,即tp1第一个成员的类型。
tuple对象间关系运算:
只能是同类型且同数量成员的tuple才能比较。
在比较时与string类似,按照成员顺序依次对比,当前成员对比不同时,tuple对比结果即当前成员对比结果;当前成员对比相同时,对比下一个成员。
auto tp1 = make_tuple(6, 2);
auto tp2 = make_tuple(1, 9);
auto tp3 = make_tuple("world", "hello");
bool judge1 = (tp1 > tp2);//结果为1
bool judge2 = (tp1 == tp2);//结果为0
bool judge3 = (tp1 > tp3);//错误,成员类型不同
tuple交换数据:
auto tp1 = tuple(1, 2, "");
auto tp2 = tuple(3, 4, "world");
tp2.swap(tp1);//数据交换
tuple解包:
auto tp1 = tuple(1, 2, "");
auto tp2 = tuple(3, 4, "world");
int a, b;
string str;
tie(a, b, str) = tp2;//使用tie来解包
tuple作为返回值时可以间接返回多个值,可理解成将多个返回值“打包”后返回。
tuple func(int a, int b, string str)
{
return tuple(a, str, b);
}
int main()
{
auto ret = func(1, 2, "hello");
cout << get<0>(ret);
return 0;
}