C++标准库(七):tuple 类型

本文为《C++ Primer》的读书笔记

#include <tuple>

tuple是类似pair的模板。不同tuple类型的成员类型可以不相同,tuple可以有任意数量的成员

每个确定的tuple类型的成员数目是固定的

定义和初始化tuple

在这里插入图片描述

注意:第二个为每个成员提供初始值的初始化方式,由于对应的构造函数是explicit的,因此只能使用直接初始化语法

访问tuple的成员

在这里插入图片描述

要访问一个tuple的成员,就要使用一个名为get的标准库函数模板。为了使用get, 我们必须指定一个显式模板实参(必须是一个整型常量表达式), 它指出我们想要访问第几个成员。我们传递给get 一个tuple对象,它返回指定成员的引用:

auto book = get<0>(item); //返回item的第一个成员

查看tuple成员的数量和类型

如果不知道一个tuple准确的类型细节信息,可以用两个辅助类模板来查询tuple成员的数量和类型

在这里插入图片描述

扫描二维码关注公众号,回复: 12024995 查看本文章
auto item = make_tuple("0-999-78345-X", 3, 20. 00);
typedef decltype(item) trans; // trans 是item的类型

// 返回trans类型对象中成员的数量
size_t sz = tuple_size<trans>::value; //返回3
// cnt的类型与item中第二个成员相同
tuple_element<1, trans>::type cnt = get<1>(item); // cnt是一个int

关系和相等运算符

在这里插入图片描述
只有两个tuple具有相同数量的成员时, 我们才可以比较它们

由于tuple定义了<==运算符, 我们可以将tuple序列传递给算法, 并且可以在无序容器中将tuple作为关键宇类型

使用tuple返回多个值

tuple的一个常见用途是从一个函数返回多个值。例如,我们的书店可能是多家连锁书店中的一家。每家书店都有一个销售记录文件,保存每本书近期的销售数据。我们可能希望在所有书店中查询某本书的销售情况

假定每家书店都有一个销售记录文件。每个文件都将每本书的所有销售记录存放在一起。进一步假定已有一个函数可以读取这些销售记录文件, 为每个书店创建一个vector<Sales_data>, 并将这些vector 保存在vectorvector中:

// files中的每个元素保存一家书店的销售记录
vector<vector<Sales_data>> files;

我们将编写一个函数, 对于一本给定的书, 在files中搜索出售过这本书的书店。对每家有匹配销售记录的书店,我们将创建一个tuple来保存这家书店的索引和两个迭代器。索引指出了书店在files 中的位置, 而两个迭代器则标记了给定书籍在此书店的vector<Sales_ data>中第一条销售记录和最后一条销售记录之后的位置


我们首先编写查找给定书籍的函数:

// matches 有三个成员: 一家书店的索引和两个指向书店vector 中元素的迭代器
typedef tuple<vector<Sales_data>::size_type,
			vector<Sales_data>::const_iterator,
			vector<Sales_data>::const_iterator> matches;
			
// files 保存每家书店的销售记录,book 表示要查找的书籍的ISBN号
// findBook 返回一个vector, 每家销售了给定书籍的书店在其中都有一项
vector<matches>
findBook(const vector<vector<Sales_data>> &files, const string &book)
{
    
    
	vector<matches> ret; 
	// 对每家书店, 查找与给定书籍匹配的记录范围(如果存在的话)
	for (auto it = files.cbegin(); it != files.cend(); ++it) {
    
    
		// 查找具有相同ISBN 的Sales_data 范围
		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));
	}
	return ret; // 如果未找到匹配记录的话, ret 为空
}

猜你喜欢

转载自blog.csdn.net/weixin_42437114/article/details/109270163