Tuple和Pair是用来处理类型不同的两个(一对)值而不需要再为它们重新定义新类而设计的。c++11后,Tuple被定义为可以用于任意大小的异质集合,而pair则仍为两个元素服务,用来组合一个双元素的tuple。
Pair
Pair可将两个value视为一个单元,被标准库中的map, multimap, unordered_map和unordered_multimap用来管理其key/value对形式存在的元素。另外需返回两个值的函数的返回值也用到了pair。
-
元素访问 Pair是一个struct而非class,故而其所有成员均是公有的,可以直接访问对应的数据成员。另外还可以采用get的方式来访问pair中的元素。以下即为访问piar中的两个值的方法。
std::pair<int, float> p(42, 3.14); p.first p.second get<0>(p) //等价于p.first get<1>(p) //等价于p.second 复制代码
-
构造函数和赋值 Pair在采用默认构造函数生成时,以各自的默认构造函数初始化后的初值来初始化。make_pair()函数无须写出类型就能生成一个piar对象。
-
Pair之间的比较 只有当两个Pair对象中的所有元素都相等,这两个Pair对象才会被视为相等。
namespace std{ template <typename T1, typename T2> bool operator== (const pair<T1, T2>& x, const pair<T1, T2>& y){ return x.first == y.first && x.second == y.second; } } 复制代码
在两个Pair对象的比较过程中,第一个元素具有较高的优先级,只有第一个元素相等了才会比较第二个元素。当第一个元素不相等时,两个Pair对象即被判定为不相等。
Tuple
Tuple是对Pair的扩展,拥有任意数量的元素。通过明白的声明或使用make_tuple()函数就可以创建一个tuple对象;通过使用get<>()函数模板就可以访问tuple对象中的元素。
#include<tuple>
#include<iostream>
#include<complex>
#include<string>
using namespace std;
int main()
{
tuple<string, int, int, complex<double>> t; //创建了四个元素的tuple
tuple<int, float, string> t1(41, 6.3, "nico"); //创建并初始化
cout<<get<0>(t1) << " " //获取t1的第一个元素
<<get<1>(t2) <<endl; //获取t1的第二个元素
auto t2 = make_tuple(22, 44, "nico");
if(t1 < t2) //比较
t1 = t2; //赋值
}
复制代码
Tuple不是寻常容器,不允许迭代元素,使用tuple的成员函数来处理其成员时,必须在编译期知道需要处理的元素的索引值,在运行期才传入索引值是不允许的。
int i;
get<i>(t1); //编译时会出错
复制代码
另外在给get函数传入无效的索引值时,编译器也会报错给予提示。
make_tuple函数会根据传入的参数的值来创建tuple对象,不需要明确指明元素的类型。
tie()函数会建立一个内含引用的tuple对象。
std::tuple <int, float, std::string> t(77, 1.1, "more light");
int i;
float f;
std::string s;
std::tie(i, f, s) = t; //将t中的值分别赋值给i, f, s, tie以i, f, s的引用建立tuple
复制代码
在使用tie()函数时,可能使用std::ignore来忽略某些元素,从而达到提取局部元素目的。
Tuple与Pair转换
可以使用一个pair对象做为初始值来初始化双元素的tuple对象,也可以将一个pair对象赋值给一个双元素的tuple对象。另外,pair也提供了一个特殊的构造函数,可以以tuple为初值来构造pair对象。