tuple元组
是一个固定大小的不同类型的集合,是泛华的std::pair。和C#中的tuple类似,但是比C#的tuple强大得多。
我们也可以把它作一个通用的结构体来用,不需要创建结构体有获取结构体的特征,在某些情况下可以取代结构体,使程序更简洁、直观。
下面看看tuple的基本用法:
先构造一个tuple:
tuple<const char,int>tp=make_tuple(sendPack,nSendSize); //构造一个tuple
这个tuple等价于一个结构体
struct A
{
char p;
int len;
}
用tuple<const char*,int>tp就可以不用创建这个结构体了,而作用使一样的。还有一种方法是使用std::tie,它会创建一个元组的左值引用。
int x=1;
int y=2;
string s="aa";
auto tp=std::tie(x,s,y);
//tp的类型实际是:std::tuple<int&,string&,int&>
再看看如何获取元组的值:
const char* data=tp.get<0>(); //获取第一个值
int len=tp.get<1>(); //获取第二个值
还有一种方法也可以获取元组的值,通过std::tie解包tuple。
int x,y;
string a;
std::tie(x,a,y)=tp;
通过tie解包后,tp中3个值会自动赋值给3个变量。解包时,如果只想解某个位置的值时,可以用std::ignore占位符来表示不解某个位置的值。
比如
std::tie(std::ignore,std::ignore,y)=tp; //只解第3个值
还有一个创建右值的引用元组方法:forward_as_tuple。
std::map<int,std::string> m;
m.emplace(std::peicewise_construct,std::forward_as_tuple(10),std::forward_as_tuple(20,'a'));
它实际上创建了一个类似于std::tupe<int&&,std::string&&>类型的tuple。
我们还可以通过tuple_cat连接多个tupe,代码如下:
//#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <tuple>
template<typename Tuple, size_t N>
struct tuple_print
{
static void print(const Tuple& t, std::ostream& os)
{
tuple_print<Tuple, N - 1>::print(t, os);
os << ", " << std::get<N - 1>(t);
}
};
// 类模板的特化版本
template<typename Tuple>
struct tuple_print<Tuple, 1>
{
static void print(const Tuple& t, std::ostream& os)
{
os << std::get<0>(t);
}
};
// operator<<
template<typename... Args>
std::ostream& operator<<(std::ostream& os, const std::tuple<Args...>& t)
{
os << "[";
tuple_print<decltype(t), sizeof...(Args)>::print(t, os);
os << "]";
return os;
}
int main()
{
std::tuple<int, std::string, float> t1(10, "Test", 3.14);
int n = 7;
auto t2 = std::tuple_cat(t1, std::make_pair("Foo", "bar"), t1, std::tie(n));
n = 10;
std::cout << t2 << std::endl;
return 1;
}
输出结果如下