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
的元素分别用于first
和second
的构造:
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));