C++类模板tuple(元组C++11)和pair的简单使用

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

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 
(公开成员函数)

operator=

赋值一个 tuple 的内容给另一个 
(公开成员函数)

swap

交换两个 tuple 的内容 

非成员函数

make_tuple

创建一个 tuple 对象,其类型根据各实参类型定义 
(函数模板)

tie

创建左值引用的 tuple,或将 tuple 解包为独立对象 
(函数模板)

forward_as_tuple

创建转发引用的 tuple 
(函数模板)

tuple_cat

通过连接任意数量的元组来创建一个tuple 
(函数模板)

std::get(std::tuple)

元组式访问指定的元素 
(函数模板)

辅助类

tuple_size

在编译时获得 tuple 的大小 
(类模板特化)

tuple_element

获得指定元素的类型 
(类模板特化)

std::uses_allocator<std::tuple>

(C++11)

特化 std::uses_allocator 类型特征 
(类模板特化)

ignore

用 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的成员变量。

成员对象

成员名类型
firstT1
secondT2

成员函数

(构造函数)

构造新的 pair 
(公开成员函数)

operator=

对 内容赋值 
(公开成员函数)

swap

(C++11)

交换内容 
(公开成员函数)

非成员函数

make_pair

创建一个 pair 对象,其类型根据各实参类型定义 
(函数模板)

operator==operator!=operator<operator<=operator>operator>=operator<=>

(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)

按字典序比较 pair 中的值 
(函数模板)

std::swap(std::pair)

(C++11)

特化 std::swap 算法 
(函数模板)

std::get(std::pair)

(C++11)

访问 pair 的一个元素 
(函数模板)

辅助类

std::tuple_size<std::pair>

(C++11)

获得 pair 的大小 
(类模板特化)

std::tuple_element<std::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元组的基本用法(总结)

tuple

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SOC罗三炮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值