pair

pair是用来处理类型相同或不同的一对值的数据结构,定义于,支持下列操作:

函数作用
pair<T1, T2> p默认构造函数
pair<T1, T2> p(val1, val2)构造函数,用val1和val2为初值
pair<T1, T2> p(rv1, rv2)移动语义构造函数,rv1和rv2为右值引用
pair<T1, T2> p(piecewise_construct, t1, t2)构造函数,t1和t2是tuple类型
pair<T1, T2> p(p2)拷贝构造函数
pair<T1, T2> p(rv)移动语义构造函数
p = p2赋值操作
p = rv移动语义的赋值操作
p.first访问成员变量
p.second访问成员变量
p1.swap(p2)交换p1和p2数据
swap(p1, p2)等同于p1.swap(p2)
get<0>§等价于p.first
get<1>§等价于p.second
==、!=、<、>、<=、>=比较操作
make_pair<val1,val2>返回一个pair
tuple_size<>::value获取元素个数,对于pair就是2
tuple_element<>::type获取指定元素类型

分段构造函数

std::piecewise_construct必须作为第一传参,第二、第三传参类型为tuple。执行的操作是,两个tuple的元素分别用于firstsecond的构造:

pair <string, vector<int>>
      foo (piecewise_construct, forward_as_tuple("sample"), forward_as_tuple(2,100));
      
cout << "foo.first: " << foo.first << '\n';
cout << "foo.second:";
for (int& x: foo.second) std::cout << ' ' << x;
std::cout << '\n';
return 0;

// 输出
// foo.first: sample
// foo.second: 100 100

拷贝构造函数

pair的拷贝构造函数有两个版本,一个是显式接受相同类型的pair传参,一个是成员模板函数。成员模板函数主要是为了支持隐式类型转换:

// <utility>中成员模板拷贝构造函数源码
template<class _Other1,
		class _Other2,
		enable_if_t<conjunction_v<
			is_constructible<_Ty1, const _Other1&>,
			is_constructible<_Ty2, const _Other2&>,
			is_convertible<const _Other1&, _Ty1>,
			is_convertible<const _Other2&, _Ty2>
		>, int> = 0>
		constexpr pair(const pair<_Other1, _Other2>& _Right)
			_NOEXCEPT_COND(is_nothrow_constructible_v<_Ty1, const _Other1&>
				&& is_nothrow_constructible_v<_Ty2, const _Other2&>)	// strengthened
		: first(_Right.first), second(_Right.second)
		{
		}

这个模板除了支持隐式类型转换,值得注意的是可以在编译期判断两个类型是否支持隐式类型转换,这应该是通过is_constructible和is_convertible实现的(但是不明白在不支持隐式类型转换的情况下,为什么找不到函数定义,应该已经实例化了函数模板):

	pair<int, int> p1(1, 1);
	pair<float, float> p2(p1);			// OK
	pair<string, string> p3(p1);		// error

除了拷贝构造函数,赋值操作符也以成员函数模板的形式支持隐式类型转换。

make_pair

make_pair是一个模板函数,根据传参生成pair对象并返回,但允许不指定模板实参:

std::make_pair(42, 'a');

C++11以后,make_pair支持移动语义和引用语义:

// 移动语义
std::string s, t;
auto p = std::make_pair(std::move(s), std::move(t));

// 引用语义
int i = 0;
auto p = std::make_pair(std::ref(i), std::ref(i));
### C++ 中 `pair` 的定义与用法 #### 什么是 `pair` 在 C++ 中,`pair` 是一种简单的结构,用于将两个相关联的值绑定在一起。它通常被用来表示键值对或成对存储的数据[^2]。 #### 定义与初始化 可以通过多种方式定义和初始化 `pair` 对象: 1. **直接构造** 使用构造函数显式创建 `pair` 对象。 ```cpp std::pair<int, double> p1(10, 3.14); ``` 2. **使用 `make_pair` 函数** 这是一种更简洁的方式,尤其适用于模板推导场景。 ```cpp std::pair<int, double> p2 = std::make_pair(10, 3.14); ``` 需要注意的是,`make_pair` 会自动进行类型提升。例如: ```cpp std::pair<int, float> p3(1, 1.1f); // second 类型为 float auto p4 = std::make_pair(1, 1.1f); // second 被提升为 double ``` 上述情况可能导致意外的行为,在实际编程中需特别留意[^3]。 3. **通过复制构造** 支持拷贝构造来初始化新的 `pair` 对象。 ```cpp std::pair<int, double> p1(1, 1.2); std::pair<int, double> p2 = p1; // 复制构造 ``` 4. **赋值操作** 已存在的 `pair` 对象可通过赋值运算符更新其值。 ```cpp std::pair<int, double> p3; p3 = p1; // 赋值操作 ``` #### 成员访问 `pair` 提供了 `.first` 和 `.second` 来分别访问其中的第一个和第二个元素。 ```cpp std::cout << p1.first << ", " << p1.second << std::endl; ``` #### 应用场景 - 存储关联数据:如二维坐标 `(x, y)` 或键值对 `(key, value)`。 - 返回多值:当函数需要返回多个值时,可以用 `pair` 将它们打包。 - 数据结构组件:作为复杂数据结构的一部分,比如 `map` 和 `unordered_map` 的内部实现[^2]。 #### 使用 `typedef` 简化定义 如果程序中频繁使用某种特定类型的 `pair`,可以借助 `typedef` 关键字简化声明过程。 ```cpp typedef std::pair<std::string, std::string> ReplacePair; ReplacePair rp1("old", "new"); ReplacePair rp2("hello", "world"); std::cout << rp1.first << "->" << rp1.second << std::endl; std::cout << rp2.first << "->" << rp2.second << std::endl; ``` --- ### Pair Programming(结对编程) 除了技术层面的 `pair` 结构外,还存在另一种名为 “Pair Programming” 的软件开发实践方法。这是一种敏捷开发中的协作模式,指两名开发者共同完成某项任务。两人共享同一台计算机,轮流担任驾驶员(Driver)和导航员(Navigator)的角色[^5]。 这种模式的优势在于能够实时审查代码质量、促进知识分享以及提高团队沟通效率。 --- 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值