功能简介
std::tuple是c++11提供的新模板类,在很多流行语言都有对应的实现,一般翻译为元组。使用它可以把多个不同类型的变量组合成一个对象。
简单示例
以下是std::tuple的简单示例(来源:https://en.cppreference.com/w/cpp/utility/tuple)
#include <tuple>
#include <iostream>
#include <string>
#include <stdexcept>
std::tuple<double, char, std::string> get_student(int id)
{
// C++11构建tuple的写法
if (id == 0) return std::make_tuple(3.8, 'A', "Lisa Simpson");
// C++17提供了更方便的构建tuple的写法
//if (id == 0) return { 3.8, 'A', "Lisa Simpson" };
if (id == 1) return std::make_tuple(2.9, 'C', "Milhouse Van Houten");
if (id == 2) return std::make_tuple(1.7, 'D', "Ralph Wiggum");
throw std::invalid_argument("id");
}
int main()
{
auto student0 = get_student(0);
// 通过下标位置获取tuple中对应的元素
std::cout << "ID: 0, "
<< "GPA: " << std::get<0>(student0) << ", "
<< "grade: " << std::get<1>(student0) << ", "
<< "name: " << std::get<2>(student0) << '\n';
// 通过tie将tuple中的元素解构至多个变量中
double gpa1;
char grade1;
std::string name1;
std::tie(gpa1, grade1, name1) = get_student(1);
std::cout << "ID: 1, "
<< "GPA: " << gpa1 << ", "
<< "grade: " << grade1 << ", "
<< "name: " << name1 << '\n';
// C++17提供了更方便的解构写法
//auto [ gpa2, grade2, name2 ] = get_student(2);
//std::cout << "ID: 2, "
// << "GPA: " << gpa2 << ", "
// << "grade: " << grade2 << ", "
// << "name: " << name2 << '\n';
}
和struct比较
先看例子,再做比较
struct student {
double gpa;
char grade;
std::string name;
};
student get_student(int id) {
if (id == 0) {
student s;
s.gpa = 3.8;
s.grade = 'A';
s.name = "Lisa Simpson";
return s;
}
// ...省略构建其余id的重复代码,只做简单演示
}
int main {
auto student0 = get_student(0);
std::cout << "ID: 0, "
<< "GPA: " << student0.gpa << ", "
<< "grade: " << student0.grade << ", "
<< "name: " << student0.name << '\n';
// ...省略获取其余id的重复代码,只做简单演示
}
相比较于std::tuple,struct需要定义结构体这个复合类型。
如果单说以上所举例的这个场景,个人觉得struct的写法表意更清晰些。
原因是函数get_student所返回的gpa、grade、name三个元素变量在含义上本身是非常紧密的。
假设我们除了这个函数,还有其他地方需要同时使用这三个变量,比如update_student或print_student等,那么struct的写法将更合适些。
多说一句,作为开发,我们要保持学习新知识的习惯。但是不能有了新锤子,就看哪都是钉子。为了用新技术而用。
而应该带着新锤子,观察和思考哪有合适钉子,再合理运用。
和std::pair比较
先看例子,再做比较
std::pair<double, std::pair<char, std::string> > get_student(int id) {
if (id == 0) {
return std::make_pair(3.8, std::make_pair('A', "Lisa Simpson"));
}
// ...省略构建其余id的重复代码,只做简单演示
}
int main() {
auto student0 = get_student(0);
std::cout << "ID: 0, "
<< "GPA: " << student0.first << ", "
<< "grade: " << student0.second.first << ", "
<< "name: " << student0.second.second << '\n';
// ...省略获取其余id的重复代码,只做简单演示
return 0;
}
相比较于std::tuple,std::pair如果想要支持多于2个的变量,需要多层嵌套或结合struct使用。
std::tie的其他用法
std::tie除了第一个例子中演示的用于解构std::tuple中的元素,还可以用来将多个变量构造成std::tuple,从而做大小比较。例如 https://en.cppreference.com/w/cpp/utility/tuple/tie 中演示的例子。这种写法更modern些~
get函数
// map::find
#include <iostream>
#include <map>
int main ()
{
std::map<char,int> mymap;
std::map<char,int>::iterator it;
mymap['a']=50;
mymap['b']=100;
mymap['c']=150;
mymap['d']=200;
it = mymap.find('b');
if (it != mymap.end())
mymap.erase (it);
// print content:
std::cout << "elements in mymap:" << '\n';
std::cout << "a => " << mymap.find('a')->second << '\n';
std::cout << "c => " << mymap.find('c')->second << '\n';
std::cout << "d => " << mymap.find('d')->second << '\n';
return 0;
}
输出:
elements in mymap:
a => 50
c => 150
d => 200