tuple(元组)
定义于头文件 <tuple>,C++11特性;
简介
tuple是一个固定大小的异类值汇集,也就是说tuple是一个固定大小的不同类型值的集合,是泛化的std::pair。我们也可以把他当做一个通用的结构体来用,不需要创建结构体又获取结构体的特征,在某些情况下可以取代结构体使程序更简洁,直观。std::tuple理论上可以有无数个任意类型的成员变量,而std::pair只能是2个成员,因此在需要保存3个及以上的数据时就需要使用tuple元组了。
等价结构体
struct person {
char *m_name;
char *m_addr;
int *m_ages;
};
//可以用tuple来表示这样的一个结构类型,作用是一样的。
std::tuple<const char *, const char *, int>
tuple的创建和初始化
std::tuple<T1, T2, TN> t1; //创建一个空的tuple对象(使用默认构造),它对应的元素分别是T1和T2...Tn类型,采用值初始化。
std::tuple<T1, T2, TN> t2(v1, v2, ... TN); //创建一个tuple对象,它的N个元素分别是T1和T2 ...Tn类型; 要获取元素的值需要通过tuple的成员get<Ith>(obj)进行获取(Ith是指获取在tuple中的第几个元素,请看后面具体实例)。
std::tuple<T1&> t3(ref&); // tuple的元素类型可以是一个引用
std::make_tuple(v1, v2); // 像pair一样也可以通过make_tuple进行创建一个tuple对象
成员函数
构造新的 tuple (公开成员函数) | |
赋值一个 tuple 的内容给另一个 (公开成员函数) | |
交换两个 tuple 的内容 |
非成员函数
创建一个 tuple 对象,其类型根据各实参类型定义 (函数模板) | |
创建左值引用的 tuple,或将 tuple 解包为独立对象 (函数模板) | |
创建转发引用的 tuple (函数模板) | |
通过连接任意数量的元组来创建一个tuple (函数模板) | |
| 元组式访问指定的元素 (函数模板) |
辅助类
在编译时获得 tuple 的大小 (类模板特化) | |
| 获得指定元素的类型 (类模板特化) | |
| std::uses_allocator<std::tuple> (C++11) | 特化 std::uses_allocator 类型特征 (类模板特化) |
用 tie 解包 tuple 时用来跳过元素的占位符 (常量) |
#include <iostream>
#include<string>
#include<set>
#include<algorithm>
#include<iterator>
#include<vector>
#include<tuple>
using namespace std;
int main()
{
//1. tuple 构造函数初始化
tuple<int, string, int, double> t1;
tuple<int, string, int, double> t2(12, "hello", 34, 5.6);
t1 = t2;
//2.使用 std::make_tuple 生成tuple对象
tuple<int, int, int, double> t3 = make_tuple(1, 2, 3, 4.5);
//3.获取元组元素个数--std::tuple_size
cout << "t1元素个数:"<< tuple_size<decltype(t1)>::value << endl;
//4.获取第i个元素--std::get<i>(tuple)
cout << "t2的第二个元素: "<< get<2>(t2) << endl;
// tuple 不支持迭代,只能通过元素索引(或tie解包)进行获取元素的值。
// 但是给定的索引必须是在编译器就已经给定,不能在运行期进行动态传递,否则将发生编译错误:
//for (int i = 0; i < 3; i++)
// std::cout << std::get<i>(t3) << " "; //将引发编译错误
//5.获取元素的类型
std::tuple<std::string, int> tp("Sven", 20);
// 得到第二个元素类型
std::tuple_element<1, decltype(tp)>::type ages;
// ages 就为int类型
ages = std::get<1>(tp);
std::cout << "ages: " << ages << '\n';
//6.利用tie进行解包元素的值
int one, three;
string two;
double four;
//解包
tie(one, two, three, four) = t2;
cout << "t2第0个元素:" << one << endl;
cout << "t2第1个元素:" << two << endl;
cout << "t2第2个元素:" << three << endl;
cout << "t2第3个元素:" << four << endl;
//7. tuple 元素的引用
std::tuple<std::string, int, float> tp1("Sven Cheng", 77, 66.1);
std::string name;
int weight;
float f;
auto tp2 = std::make_tuple(std::ref(name), std::ref(weight), std::ref(f)) = tp1;
std::cout << "Before change: " << '\n';
std::cout << "name: " << name << ", ";
std::cout << "weight: " << weight << ", ";
std::cout << "f: " << f << '\n';
name = "Sven";
weight = 80;
f = 3.14;
std::cout << "After change: " << '\n';
std::cout << "element 1st: " << std::get<0>(tp2) << ", ";
std::cout << "element 2nd: " << std::get<1>(tp2) << ", ";
std::cout << "element 3rd: " << std::get<2>(tp2) << '\n';
return 0;
}
//结果:
/*
*
t1元素个数:4
t2的第二个元素: 34
ages: 20
t2第0个元素:12
t2第1个元素:hello
t2第2个元素:34
t2第3个元素:5.6
Before change:
name: Sven Cheng, weight: 77, f: 66.1
After change:
element 1st: Sven, element 2nd: 80, element 3rd: 3.14
*/
pair
定义于头文件 <utility>
std::pair 是类模板,提供在一个单元存储两个相异类型对象的途径。 pair 是 std::tuple 的拥有两个元素的特殊情况。
pair是将2个数据组合成一组数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存。另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair。 pair的实现是一个结构体,主要的两个成员变量是first second 因为是使用struct不是class,所以可以直接使用pair的成员变量。
成员对象
| 成员名 | 类型 |
first | T1 |
second | T2 |
成员函数
| 构造新的 pair (公开成员函数) | |
| 对 内容赋值 (公开成员函数) | |
| (C++11) | 交换内容 (公开成员函数) |
非成员函数
创建一个 pair 对象,其类型根据各实参类型定义 (函数模板) | |
| operator==operator!=operator<operator<=operator>operator>=operator<=> (C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20) | 按字典序比较 pair 中的值 (函数模板) |
| (C++11) | 特化 std::swap 算法 (函数模板) |
| (C++11) | 访问 pair 的一个元素 (函数模板) |
辅助类
| (C++11) | 获得 pair 的大小 (类模板特化) |
| (C++11) | 获得 pair 中元素的类型 (类模板特化) |
#include <iostream>
#include<string>
#include<set>
#include<algorithm>
#include<iterator>
#include<vector>
#include<tuple>
#include<utility>
#include <complex>
using namespace std;
int main()
{
//1.初始化
std::pair<int, float> p1;
std::cout << "Value-initialized: "
<< p1.first << ", " << p1.second << '\n';
std::pair<int, double> p2(42, 0.123);
std::cout << "Initialized with two values: "
<< p2.first << ", " << p2.second << '\n';
std::pair<char, int> p4(p2);
std::cout << "Implicitly converted: "
<< p4.first << ", " << p4.second << '\n';
std::pair<std::complex<double>, std::string> p6(
std::piecewise_construct,
std::forward_as_tuple(0.123, 7.7),
std::forward_as_tuple(10, 'a'));
std::cout << "Piecewise constructed: "
<< p6.first << ", " << p6.second << '\n';
//使用make_pair
pair<int, double> p7 = make_pair(12, 3.4);
cout << "p7: " << p7.first << ", " << p7.second << endl;
p7.first = 666;
p7.second = 99.9;
cout << "p7: " << p7.first << ", " << p7.second << endl;
return 0;
}
/*
*
Value-initialized: 0, 0
Initialized with two values: 42, 0.123
Implicitly converted: *, 0
Piecewise constructed: (0.123,7.7), aaaaaaaaaa
p7: 12, 3.4
p7: 666, 99.9
*/
参考链接:

本文详细介绍了C++中的元组(tuple)和pair,包括它们的定义、创建与初始化、成员函数、非成员函数以及应用场景。元组是一种固定大小的异类值汇集,可以替代结构体,而pair则用于存储两个相异类型的对象,常用于函数返回多个值。文章通过实例展示了如何使用tuple的get函数获取元素,以及如何通过tie解包元素。同时,还对比了tuple与pair的区别和使用场景。
2730

被折叠的 条评论
为什么被折叠?



