15.C++11之tuple与tie
1. tuple 基本语法
- std::tuple 是类似 pair 的模板。每个 pair 的成员类型都可不相同,但每个 pair 都恰好有两个成员。std::tuple 类型的成员类型也不可相同,另外一个 std::tuple 可以有任意数量的成员。
- 但我们希望 将一些数据组合成单一对象,但又不想麻烦地定义一个新数据结构来表示这些数据 时,std::tuple 是非常有用的。我们可以将 std::tuple 看作一个”快速而随意”的数据结构。
- 一个std::tuple 类型的成员数目是没有限制的,因此,tuple 的成员都是未命名的。要访问一个tuple的成员,就要使用一个名为 get 的标准库函数模板。
- 为了使用 tuple_size 或 tuple_element,我们需要知道一个 tuple 对象的类型。与往常一样,确定一个对象的类型的最简单方法就是使用 decltype。
- std::tuple 的一个 常见用途是从一个函数返回多个值。
- std::tuple 中元素是被紧密地存储的(位于连续的内存区域),而不是链式结构。
- std::tuple 是一个编译期就确定大小的容器,可以容纳不同类型的元素。多元组类型在当前标准库中被定义为可以用任意数量参数初始化的类模板。每一模板参数确定多元组中一元素的类型。所以,多元组是一个多类型、大小固定的值的集合。
2. tuple 与 struct
-
如果您关心命名问题(即,事实上,用户定义的结构体 struct 对其 每个成员都有一个有意义的名称 ,而元组却没有),那么您就要求元组实现一些它不应该实现的目标。
-
简单地说,如果您想要返回的是具有高级语义的数据包,并且您想要使用的包结构将来可能会被重用,那么您可能应该使用结构,甚至是成熟的类。
-
然而,Tuple并不是为这种情况而设计的;相反,应用元组的情况是,您所需要的只是即时获得的轻量级打包机制,并且在使用之后可能会丢弃它。
3. 示例代码
#include <tuple>
#include <functional>
#include <utility>
#include <typeinfo>
void Person::doTupleTest()
{
//1.构造tuple
std::tuple<int, std::string, double> a1(1, "rock", 99.5);
std::tuple<int, std::string, double> a2(std::make_tuple(2, "bob", 95.5));
//2.读取tuple中的值
std::cout << std::get<0>(a1) << '\t' << std::get<1>(a1).c_str() << '\t' << std::get<2>(a1) << std::endl;
//3.修改tuple中的值
std::get<2>(a1) = 100;
std::cout << std::get<0>(a1) << '\t' << std::get<1>(a1).c_str() << '\t' << std::get<2>(a1) << std::endl;
//4.搭配 typedef
typedef std::tuple<int, std::string, double> MyTuple;
MyTuple a3(3, "lily", 100);
std::cout << std::get<0>(a3) << '\t' << std::get<1>(a3).c_str() << '\t' << std::get<2>(a3) << std::endl;
std::get<2>(a3) = 101.0;
std::cout << std::get<0>(a3) << '\t' << std::get<1>(a3).c_str() << '\t' << std::get<2>(a3) << std::endl;
//5.获取 tuple 中的元素个数
auto a3Size = std::tuple_size<decltype(a3)>::value;
std::cout << "the element size of a3 is " << a3Size << std::endl;
//6.结合 tie ,对 tuple 进行解包为独立对象 (不需要的元素可以 ignor)
int a1No = 0;
double a1Score = 0.0;
std::tie(a1No, std::ignore, a1Score) = a1;
std::cout << "a1No:" << a1No << "\t\ta1Score:" << a1Score << std::endl;
}
4. tie 基本语法
- std::tie 建立左值引用的 tuple,或将 tuple 解包为独立对象。
- std::tie 可用于解包 std::pair,由于 std::tuple 拥有从 pair 的转换赋值。
得到
5. 实例代码
//1.解包tuple或批量赋值
std::tuple<int, std::string, double> b1(11, "rockman", 99.5);
int n;
std::string s;
double d;
std::tie(n, s, d) = b1;
std::cout << "n:" << n << "\t\ts:" << s.c_str() << "\t\td:" << d <<std::endl;
//2.解包pair
std::map<int, std::string> m;
std::map<int, std::string>::iterator it;
bool isInserted;
std::tie(it, isInserted) = m.insert(std::make_pair(1, "rock"));
if (isInserted)
{
std::cout << "Value was inserted successfully!" << std::endl;
}
//3.搭配ignor只提取关注的值
std::tie(std::ignore, s, std::ignore) = b1;
std::cout << "s: " << s.c_str() << std::endl;
//tie搭配ignor判断pair返回值非常方便
std::tie(std::ignore, isInserted) = m.insert(std::make_pair(2, "bob"));
if (isInserted)
{
std::cout << "Value was inserted successfully!" << endl;
}
4. 参考资料
https://blog.csdn.net/fengbingchun/article/details/72835446
https://www.jb51.net/article/191040.htm
道虽迩,不行不至;事虽小,不为不成。