Class pair 可将两个 value 视为一个单元。C++ 标准库内多处用到了这个 class pair。尤其容器 map,multimap,unordered_map 和 unordered_multimap 就是使用 pair 来管理其以key/value pair 形式存在的元素。任何函数如果需返回两个 value,也需要用到 pair,例如minmax()。
Struct pair定义于 < utility >头文件 中。原则上可以对 pair<> 执行 create、copylassign/swap 及 compare 操作。此外 pair 还提供 first_type 和 second_type 类型定义式,用来表示第一 value 和第二 value 的类型。
pair 的操作函数
操作函数 | 描述 |
---|---|
pair<T1, T2> p | Default 构造函数,建立个 pair,其元素类型分别为 T1 和 T2,各自以其 default 构造函数初始化 |
pair<T1, T2> p(vall, vall) | 建立一个 pair,元素类型分别为 T1 和 T2,以 vall 和 vall 为初值 |
pair<T1, T2> p(rv1, rv2) | 建立一个 pair,元素类型分别为 T1 和 T2,以 rv1 和 rv2 进行搬移式初始化(move initialized) |
pair<T1, T2> p(piecewise_construct, t1, t2) | 建立一个 pair,元素类型分别为 tuple T1 和 T2,以 tuple t1 和 t2 的元素为初值 |
pair<T1, T2> p(p2) | Copy 构造函数,建立 p 成为 p2 的拷贝 |
pair<T1, T2> p(rv) | Move 构造函数,将 rv 的内容移至 p(允许隐式类型转换) |
p = p2 | 将 p2 赋值给 p (始自C++11;允许隐式类型转换) |
p = rv | 将 rv 的值 move assign 给 p (始自C++11;允许隐式类型转换) |
p.first | 获得 pair 内的第一 value (直接成员访问) |
p.second | 获得 pair 内的第二 value (直接成员访问) |
get<0>( p ) | 等价于 p.first (始自C++11) |
get<1>( p ) | 等价于 p.second (始自C++11) |
p1 == p2 | 返回“是否 p1 等于 p2 ”(等价于 p1.first == p2.first && p1.second == p2.second) |
p1 != p2 | 返回“是否 p1 不等于 p2 ” ( !(p1 == p2) ) |
p1 < p2 | 返回“是否 p1 小于 p2 ”(比较 first,如果相等则比较 second ) |
p1 > p2 | 返回“是否 p1 比 p2 更大” ( 亦即 p2 < p1 ) |
p1 <= p2 | 返回“是否 p1 小于等于 p2 ” ( !( p2 < p1 ) ) |
p1 >= p2 | 返回“是否 p1 大于等于 p2 ”( !( p1 < p2 ) ) |
p1.swap(p2) | 互换 p1 和 p2 的数据 (始自C++11) |
swap(p1, p2) | 同上 (是个全局函数) (始自C++11) |
make_pair(vall, val2) | 返回一个 pair,带有 val1 和 val2 的类型和数值 |
创建和赋值
pair 包含两个数值,与容器一样,pair 也是一个模板类型。在创建 pair 对象时,必须提供两个类型名,两个对应的类型名的类型不必相同。
pair<string, string> p1; //创建p1、p2、p3、p4四个空pair对象
pair<string, int> p2;
pair<string, vector<int>> p3;
pair<int, float> p4;
pair<int, float> p4;就是以 int() 和 float() 来初始化 p4,这两个构造函数都传回零值。所以 p4 的 first 和 second 初始值都是 0。
也可以在定义时进行初始化:
pair<string, string> p1("qw", "qy");//创建一个p1对象,并初始化为qw和qy
pair<string, int> p2("qwjy", "0");
pair<string, int> p3(p2); //拷贝初始化
pair 的赋值:
typedef pair<string, int> P;//利用typedef简化定义
P p1("qw", 0);
P p2 = p1;
元素访问
为了让程序能够处理 pair 的两个值,它提供了“直接访问对应数据成员”的能力。事实上由于它是个 struct 而不是 class,以至于所有成员都是 public:
namespace std {
template <typename T1, typename T2>
struct pair {
T1 first;
T2 second;
};
}
访问两个元素操作可以通过 first 和 second 访问。
pair<string, int> p("qwjy", 1);
printf("%s--%d", p.first.c_str(), p.second);//输出:qwjy--1
p.first = "qw";
p.second = 0;
printf("%s--%d", p.first.c_str(), p.second);//输出:qw--0
make_pair() 创建新的 pair 对象
函数 make_pair() 无须写出类型就能生成一个 pair 对象。函数的声明和定义如下:
namespace std {
template <template T1, template T2>
pair<T1, T2> make_pair(const T1& x, const T2& y) {
return pair<T1, T2>(x,y);
}
}
利用 make_pair() 创建新的 pair 对象:
pair<string, int> p;
p = make_pair("qwjy", 1);
printf("%s--%d", p.first.c_str(), p.second);//输出:qw--0
pair 之间的比较
比较两个 pair 对象,C++ 标准库提供了大家惯用的操作符。
两个 pair 对象内的所有元素都相等,这两个 pair 对象才被视为相等(equal ) :
namespace std {
template <template T1, template T2>
bool operator == (const pair<T1, T2>& x, const pair<T1, T2>& y) {
return x.first == y.first && x.second == y.second;
}
}
两个 pair 对象内的存在元素不相等,这两个 pair 对象才被视为不相等:(!(x == y))
namespace std {
template <template T1, template T2>
bool operator != (const pair<T1, T2>& x, const pair<T1, T2>& y) {
return x.first != y.first || x.second != y.second;
}
}
两个 pair 互相比较时,第一元素具有较高的优先级。所以如果两个 pair 的第一元素不相等,其比较结果就成为整个比较的结果。如果 first 相等,才继续比较 second,并把比较结果当作整体结果:(p1 < p2)
namespace std {
template <template T1, template T2>
bool operator < (const pair<T1, T2>& x, const pair<T1, T2>& y) {
return x.first < y.first || (!(y.first < x.first) && x.second < y.second);
}
}
p1 > p2:(p2 < p1)
namespace std {
template <template T1, template T2>
bool operator > (const pair<T1, T2>& x, const pair<T1, T2>& y) {
return x.first > y.first || (!(y.first > x.first) && x.second > y.second);
}
}
p1 <= p2:(!(p2 < p1))
namespace std {
template <template T1, template T2>
bool operator <= (const pair<T1, T2>& x, const pair<T1, T2>& y) {
return x.first <= y.first || (!(y.first < x.first) && x.second <= y.second);
}
}
p1 >= p2:(!(p1 < p2))
namespace std {
template <template T1, template T2>
bool operator >= (const pair<T1, T2>& x, const pair<T1, T2>& y) {
return x.first >= y.first || (!(y.first > x.first) && x.second >= y.second);
}
}
参考书籍:C++标准库(第2版)——侯捷译