赞
踩
C++11引入了一个新的较实用的模板类型,std::tuple
,也即是元组。元组是一个固定大小的不同类型(异质,heterogeneous)值的集合,也即它可以同时存放不同类型的数据。
类似于python中用小括号表示的元组类型。C++已有的std::pair
类型类似于一个二元组,可看作是std::tuple
的一个特例,std::tuple
也可看作是std::pair
的泛化。std::pair
的长度限制为2,而std::tuple
的元素个数为0~任意个。
get<0>
是第一个成员。tuple_size
或tuple_element
,我们需要知道一个元组对象的类型。与往常一样,确定一个对象的类型的最简单方法就是使用decltype
。{
std::tuple<int, double, std::string> first; // 创建一个空的元组,需要指定元组元素的数据类型,调用各个成员的默认构造函数进行初始化。
std::tuple<int, double, std::string> second(first); // 拷贝构造
std::tuple<int, char> third(10, 'a'); // 创建并初始化,使用小括号初始化
std::tuple<int, std::string, double> fourth{42, "Test", -3.14}; // 创建并初始化,使用新的大括号初始化列表方式初始化
std::tuple<int, char> fifth(std::make_tuple(20, 'b')); // 移动构造,使用模板库的make_tuple
first = std::make_tuple(1, 3.14, "tuple"); // 移动赋值
int i_third = 3;
std::tuple<int&> sixth(std::ref(i_third)); // 创建一个元组,元组的元素可以被引用
}
std::get<N>()
{
int n = 1;
auto t = std::make_tuple(10, "Test", 3.14, std::ref(n), n);
// get尖括号中的值必须是一个整型常量表达式。从0开始计数,意味着get<0>是第一个成员。
std::cout << "The value of t is " << "("
<< std::get<0>(t) << ", " << std::get<1>(t) << ", "
<< std::get<2>(t) << ", " << std::get<3>(t) << ", "
<< std::get<4>(t) << ")\n";
// 由于get返回指定元素的引用,所以可用来修改指定位置的元素的值。此处因为第4个元素是引用类型,所以被引用的值也会改变
std::get<3>(t) = 9;
std::cout << n << std::endl;
}
使用std::tuple_size<>()
{
std::tuple<char, int, long, std::string> first('A', 2, 3, "4");
int i_count = std::tuple_size<decltype(first)>::value; // 使用std::tuple_size计算元组个数
std::cout << "the number of elements of a tuple:" << i_count << "\n";
}
std::tie()
元组包含一个或者多个元素,使用std::tie
解包: 首先需要定义对应元素的变量,再使用tie。
{ // std::tie: function template, Constructs a tuple object whose elements are references // to the arguments in args, in the same order // std::ignore: object, This object ignores any value assigned to it. It is designed to be used as an // argument for tie to indicate that a specific element in a tuple should be ignored. int myint; char mychar; std::tuple<int, float, char> mytuple; mytuple = std::make_tuple(10, 2.6, 'a'); // packing values into tuple std::tie(myint, std::ignore, mychar) = mytuple; // unpacking tuple into variables std::cout << "myint contains: " << myint << '\n'; std::cout << "mychar contains: " << mychar << '\n'; }
获取元组中某个元素的数据类型,需要用到另外一个类型: std::tuple_element
。 语法: std::tuple_element<index, tuple>
。
{
std::tuple<int, std::string> third(9, std::string("ABC"));
// 得到元组第1个元素的类型,用元组第一个元素的类型声明一个变量
std::tuple_element<1, decltype(third)>::type val_1;
// 获取元组的第一个元素的值
val_1 = std::get<1>(third);
std::cout << "val_1 = " << val_1.c_str() << "\n";
}
使用 std::tuple_cat
执行拼接
{
std::tuple<char, int, double> first('A', 1, 2.2f);
// 组合到一起, 使用auto, 自动推导
auto second = std::tuple_cat(first, std::make_tuple('B', std::string("-=+")));
// 组合到一起,可以知道每一个元素的数据类型时什么 与 auto推导效果一样
std::tuple<char, int, double, char, std::string> third = std::tuple_cat(first, std::make_tuple('B', std::string("-=+")));
// 输出合并后的元组内容
int index = 0;
std::cout << index++ << " = " << std::get<0>(second) << "\n"; // 0 = A
std::cout << index++ << " = " << std::get<1>(second) << "\n"; // 1 = 1
std::cout << index++ << " = " << std::get<2>(second) << "\n"; // 2 = 2.2
std::cout << index++ << " = " << std::get<3>(second) << "\n"; // 3 = B
std::cout << index++ << " = " << std::get<4>(second).c_str() << "\n"; // 4 = -=+
}
元组没用提供operator []
重载,遍历起来较为麻烦,需要为其单独提供遍历模板函数
template<class T> void print_single(T const& v) { if constexpr (std::is_same_v<T, std::decay_t<std::string>>) std::cout << std::quoted(v); else if constexpr (std::is_same_v<std::decay_t<T>, char>) std::cout << "'" << v << "'"; else std::cout << v; } // helper function to print a tuple of any size template<class Tuple, std::size_t N> struct TuplePrinter { static void print(const Tuple& t) { TuplePrinter<Tuple, N-1>::print(t); std::cout << ", "; print_single(std::get<N-1>(t)); } }; template<class Tuple> struct TuplePrinter<Tuple, 1>{ static void print(const Tuple& t) { print_single(std::get<0>(t)); } }; template<class... Args> void print(const std::tuple<Args...>& t) { std::cout << "("; TuplePrinter<decltype(t), sizeof...(Args)>::print(t); std::cout << ")\n"; } // end helper function
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。