tuple 简介
  • tuple 是 C++11 新特性,定义在头文件 tuple 之中。
  • tuple 可以当作一个通用结构体使用,不需要创建结构体又获取结构体的特征,在一些情况下可以取代结构体使得程序更简洁、直观。
  • tuple 理论上可以有无数个任意类型的成员变量。
tuple 创建和初始化
std::tuple<T1, T2, TN> t1;           //@ 使用默认构造,所有的元素执行值初始化
std::tuple<T1, T2, TN> t2(v1, v2, ... TN); //@ 使用给定的值初始化
std::make_tuple(v1, v2); //@ 使用 make_tuple 创建,tuple的类型将从初始值推断出来


std::tuple<T1, T2, TN> t2(v1, v2, ... TN); 这个构造函数时 explicit 的,必须使用直接初始化语法:

tuple<size_t, size_t, size_t> threeD = (1, 2, 3); //@ error
tuple<size_t, size_t, size_t> threeD(1, 2, 3); //@ ok
tuple<size_t, size_t, size_t> threeD{ 1, 2, 3 }; //@ ok


tuple 的元素也可以是引用类型:

string name;
tuple<string&, int> tpRef(name, 30);
get<0>(tpRef) = "Sven";
cout << "name: " << name <<endl; //@ name 的值也被改变


tuple 元素的操作

获取 tuple 元素个数

tuple <int,char,double> item(10,'c',3.14);
cout<<tuple_size<decltype(item)>::value<<endl; //@ 获取tuple元素个数


获取元素的值

tuple <int,char,double> item(10,'c',3.14);
cout<<get<0>(item)<<endl; //@ get<index> (tuple)
cout<<get<1>(item)<<endl;
cout<<get<2>(item)<<endl;


tuple 不支持迭代,只能通过元素索引(或tie解包)进行获取元素的值。但是给定的索引必须是在编译器就已经给定,不能在运行期进行动态传递,否则将发生编译错误:

tuple <int,char,double> item(10,'c',3.14);
for (int i = 0; i < 3;i++)
cout << get<i>(item) << endl; //@ error


获取元素的类型

tuple <int,char,double> item(10,'c',3.14);
tuple_element<0,decltype(item)>::type ages; //@ ages 为int类型
ages = get<0>(item);
cout<<ages<<endl;


tie 解包元素的值

tuple<string,int,char> t = make_tuple("hello",1,'c');
string str;
int i;
char ch;
tie(str,i,ch) = t;
cout<<str<<endl;
cout<<i<<endl;
cout<<ch<<endl;


如果只需要 tuple 当中的几个元素,可以使用 std::ignore 进行变量占位,这样将会忽略提取对应的元素。

tuple<string,int,char> t = make_tuple("hello",1,'c');
string str;
tie(str,std::ignore,std::ignore) = t;


tuple 元素的引用

通过 make_tuple 可以提取 tuple 元素的值,将某些变量的值设给他们,并通过改变这些变量来改变 tuple 的值:

tuple<string, int, float> tp1{"Tom",9,90.5 };
string name;
int age;
float score;

auto tp2 = make_tuple(std::ref(name), std::ref(age),std::ref(score)) = tp1;
cout << name << endl;
cout << age << endl;
cout << score << endl;

name = "Mike";
age = 10;
score = 98.2;
cout << get<0>(tp2) << endl;
cout << get<1>(tp2) << endl;
cout << get<2>(tp2) << endl;


tuple 元素的比较

  • 只有两个 tuple 具有两个相同数量的元素时才可以进行比较。
  • 为了使用 == 或者 != 运算符,每对成员之间使用 == 必须是合法的。
  • 为了使用关系运算符,每对成员之间使用 < 必须是合法的。
tuple<string, string> tp1{ "1","2" };
tuple<int, int> tp2{ 1,2 };
tuple<int, int, int> tp3{ 1,2,3 };
tuple<int, int> tp4{ 0,1 };

cout << (tp1 == tp2) << endl; //@ 不同元素类型的tuple不能比较
cout << (tp1 == tp3) << endl; //@ 不同元素个数的tuple不能比较
cout << (tp2 > tp4) << endl; //@ true


两个 tuple 拼接

tuple<string, int, char> tp1{ "hi",1,'c' };
tuple<float, int> tp2{3.14,0};

auto tp = tuple_cat(tp1,tp2);
cout<<tuple_size<decltype(tp)>::value << endl; //@ 5


tuple 应用

使用 tuple 替代结构体:

struct person {
char *m_name;
char *m_addr;
int *m_ages;
};

//@ 使用 tuple 代替结构体
tuple<const char *, const char *, int>