tuple是类似于pair的模板,不同之处在于pair是两个成员,而tuple可以任意数量的成员。
图片来自C++ Primer 17.1
tuple相关使用方法
定义和初始化tuple
tuple<size_t, size_t, size_t> threeD; //三个成员都设置为0
//WAY1
tuple<string, vector<double>, int> someVal("constant", {3.14,2.718}, 42);
tuple<int, int, int> threeI = {1,2,3}; //错误
//WAY2
tuple<int, int, int> threeI{1,2,3}; //正确
//WAY3
auto someVal = make_tuple("constant", {3.14,2.718}, 42);
访问tuple的成员
pair只有两个成员,我们可以用first,second,但tuple数目没有限制,所以我们就要调用get这个标准库函数模板。从0开始计数。
auto book = get<0>(item); //返回item的第一个成员
auto price = get<1>(item); //返回item的第二个成员
如果不确定tuple的类型,可以用两个辅助模板查询
typedef decltype(item) trans; //tran是item的类型
//返回trans类型对象中成员的数量
size_t sz = tuple_size<trans>::value; //返回3
trans相当于真正类型的别名,所以当我们想要调用item的真实类型时,直接调用trans就好。
关系和相等运算符
tuple也可以使用相等和关系运算符,这些运算符会逐个对比较左侧tuple和右侧tuple的成员。只有两个tuple有相同数量的成员时,才能比较它们。
tuple<string, string> duo("1","2");
tuple<int, int> twoD(1, 2);
bool b = (duo == twoD); //错误;int和string不能比较
tuple<int, int, int> threeD(1,2,3);
b = (twoD < threeD); //错误;成员数量不同
tuple<int, int> origin(0,0);
b = (origin < twoD); //正确:b为true
使用tuple返回多个值※
以书店为例,如果我们有多家连锁店,而我在其中一家店调取销售记录,保存每本书的近期销售数据。此时我们就需要将每本书的在所有店的销售记录合并。
每本书创建一个vector<SaleDate>
一本书的所有店记录<vector<vector<SaleData>>>
// 一家书店的索引和两个指向书店vector中的元素迭代器
typedef tuple<vector<SaleData>::size_type,
vector<SaleData>::const_iterator,
vector<SaleData>::const_iterator> matches;
// files保存每家书店的销售记录
// book是我们当前要找的书名
// findBook返回一个vector,当前书在所有店的销售记录合集
vector<matches>
findBook(const vector<vector<SaleData>>& files, const string& book)
{
vector<matches> ret;
for(auto it = files.cbegin(); it != files.cend(); ++it)
{
//通过查找相同的ISBN,来获取SaleData范围
auto found = equal_range(it->cbegin(), it->cend(), book, compareISbn);
if (found.first != found.second)
{
//记住书店索引及匹配范围
ret.push_back(make_tuple(it - files.cbegin(), found.first, found.second));
}
}
}