語法書 / AA 競程語法書 下冊 / 第十單元 / pair:把兩個值綁在一起

10.11 pair:把兩個值綁在一起

有些資料天生成雙成對:平面座標的 (x, y)、一個人的身高和體重、一筆成績和它的座號。用兩個變數分開存當然可以,但「這兩個值屬於同一個東西」這件事就只存在你腦中,程式裡看不出來。pair 專治這件事:把兩個值裝進同一個變數

pair 定義在 <utility> 裡。宣告時角括號給兩個型態(可以不同),pair<int, char> 合起來同樣是一個完整的型態名稱(10.2 那條規則);兩個成員叫 firstsecond——它們就是兩個普通變數,直接讀、直接改:

#include <iostream>
#include <utility>
using namespace std;

int main() {
    pair<int, int> p = {3, 5};             // first 是 3、second 是 5
    cout << p.first << ' ' << p.second << '\n';

    pair<char, int> q = make_pair('A', 4); // 用 make_pair 造一個 pair
    q.second = 7;                          // first、second 就是兩個普通變數
    cout << q.first << ' ' << q.second << '\n';
    return 0;
}

執行結果:

3 5
A 7

給值有兩種寫法:大括號 {3, 5},或函式 make_pair(3, 5)——效果相同,看場合選順手的。

pair 的比較規則

pair 也內建比較運算子,規則跟字典序同一個精神:先比 firstfirst 平手才比 second;兩個都相等才算相等

#include <iostream>
#include <utility>
using namespace std;

int main() {
    pair<int, int> a = {2, 99};
    pair<int, int> b = {3, 1};
    cout << (a < b) << '\n';                  // first:2 < 3,second 再大也沒用
    cout << (a < make_pair(2, 100)) << '\n';  // first 平手,比 second:99 < 100
    cout << (a == make_pair(2, 99)) << '\n';  // 兩個都相等,才是相等
    return 0;
}

執行結果:

1
1
1

一個小地雷:比較的另一邊可以是 pair 變數或 make_pair(...),但不能直接寫大括號——a < {2, 100} 是編譯錯誤。大括號只能用在初始化、指派,或當作函式的引數(像下面的 push_back({3, 4}));放在比較運算子旁邊就不行。

pair 跟 vector 是天作之合:vector<pair<int, int>> 就是「一串點」——存一堆座標、一堆(成績,座號),競程天天用:

vector<pair<int, int>> pts;        // 裝「點」的 vector
pts.push_back({3, 4});
pts.push_back({1, 2});
cout << pts[0].first << ' ' << pts[1].second << '\n';   // 3 2