17.标准库特殊设施

标准库特殊设施

17.1tuple类型

tuple(定义在tuple头文件中)是类似pair的模板。不同tuple类型的成员类型也不相同,但一个tuple可以有任意数量的成员。每个确定的tuple类型的成员数目是固定的,但一个tuple类型的成员数目可以与另一个tuple类型不同。
当希望将一些数据组合成单一对象,但又不想麻烦地定义一个新数据结构来表示这些数据时,tuple是非常有用的。

在这里插入图片描述

17.1.1定义和初始化tuple

当定义一个tuple时,需要指出每个成员的类型:

// 三个成员都设置为0,值初始化。
tuple<size_t, size_t, size_t> threeD;

tuple<string, vector<double>, int, list<int>> someVal(
	"constants",
	{3.14, 2.718}, 42,
	{0, 1, 2, 3, 4, 5}
);

// 使用初始化来推断tuple的类型:tuple<const char*, int, double>
auto item = make_tuple("0-9990-78345-X", 3, 20.00);
访问tuple的成员
// 尖括号中的值必须是一个整型常量表达式
auto book = get<0>(item);	// 返回item的第一个成员
auto cnt = get<1>(item);	// 返回item的第二个成员
auto price = get<2>(item) / cnt;	// 返回item的最后一个成员
get<2>(item) *= 0.8;	// 打折20%

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

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<string, string> duo("1", "2");
tuple<size_t, size_t> twoD(1, 2);
bool b = (duo == twoD);	// 错误:不能比较size_t和string。
tuple<size_t, size_t, size_t> threeD(1, 2, 3);
b = (twoD < threeD);	// 错误:成员数量不同。
tuple<size_t, size_t> origin(0, 0);
b = (origin < twoD);	// 正确:b为true。

17.1.2使用tuple返回多个值

tuple的一个常见用途是从一个函数返回多个值。

// 书店可能是多家连锁书店中的一家。每家书店都有一个销售记录文件,保存每本书近期的销售数据。
// 可能希望在所有书店中查询某本书的销售情况。
// 假定每家书店都有一个销售记录文件。每个文件都将每本书的所有销售记录存放在一起。进一步假设
// 已有一个函数可以读取这些销售记录文件,为每个书店创建一个vector<Sales_data>,并将这些vector
// 保存在vector的vector中:vector<vector<Sales_data>> files。

// matches有三个成员:一家书店的索引和两个指向书店vector中元素的迭代器。
typedef tuple<vector<Sales_data>::size_type, 
			  vector<Sales_data>::const_iterator, 
			  vector<Sales_data>::const_iterator> matches;
// files保存每家书店的销售记录。
// findBook返回一个vector,每家销售了给定书籍的书店在其中都有一项。
vector<matches> findBook(const vector<vector<Sales_data>> &files, const string &book) {
	vector<matches> ret;	// 初始化为空vector
	// 对每家书店,查找与给定书籍匹配的记录范围(如果存在的话)。
	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为空。
}

void reportResults(istream &in, ostream &os, const vector<vector<Sales_data>> &files) {
	string s;	// 要查找的书
	while (in >> s) {
		auto trans = findBook(files, s);	// 销售了这本书的书店
		if (trans.empty()) {
			cout << s << " not found in any stores" << endl;
			continue;	// 获得下一本要查找的书
		}
		for (const auto &store : trans) {	// 对每家销售了给定书籍的书店
			// get<n>返回store中tuple的指定的成员
			os << "store " << get<0>(store) << " sales: "
			   << accumulate(get<1>(store), get<2>(store), Sales_data(s))
			   << endl;
		}
	}
}

17.2bitset类型(后续需要时再详细了解)

17.3正则表达式

17.4随机数

bernoulli_distribution类

17.5IO库再探

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值