C++之STL std::pair基本用法


std::pair 是一個結構體模板,其可於一個單元內存儲兩個相異對象。是 std::tuple 的擁有兩個元素的特殊情況。

一般來說,pair 可以封裝任意類型的對象,可以生成各種不同的 std::pair<T1, T2> 對象,可以是數組對象或者包含 std::pair<T1,T2> 的 vector 容器。

pair 還可以封裝兩個序列容器或兩個序列容器的指針。

1. 定義

#include <utility>
template<class T1, class T2> struct pair;

模板參數 T1 和 T2 是 pair 所存儲的元素的類型。

包含有兩個成員變量 first 和 second,而且都是 public 修飾的,通過 "." 訪問。

其中 first 類型為T1, second 類型為T2。

1.1 成員函數

(constructor)     constructs new pair (public member function)

operator=        assigns the contents (public member function)

swap             swaps the contents (public member function)

1.2 非成員函數

make_pair        creates a pair object of type, defined by the argument types (function template)

operator==        lexicographically compares the values in the pair (function template)
operator!=
operator<
operator<=
operator>
operator>=

std::swap(std::pair)    specializes the std::swap algorithm (function template)

std::get(std::pair)        accesses an element of a pair(function template)

2. 初始化

初始化一個 pair 可以使用構造函數,也可以使用 std::make_pair。

make_pair 定義如下:

 

template<class T1, class T2>
std::pair make_pair(T1 a, T2 b) {
    return std::pair(a, b);
}

2.1 默認構造

pair 有很多版本的引用參數,而且有一些版本的右值引用參數允許參數隱式轉換為所需的類型。

如下示例表示使用 4 種不同的方式來初始化 pair 對象:

std::string s1 {"test”}, s2{"that"};
std::pair<std::string, std::string> my_pair{s1, s2};

std::pair<std::string, std::string> your_pair {std::string {"test"},std::string {"that"}};

std::pair<std::string, std::string> his_pair {"test", std::string {"that"}};

std::pair<std::string, std::string> her_pair {"test", "that"};

第一個 pair 構造函數復制了所有參數的值。

第二個移動參數值。

第三個為了隱式轉換而將第一個參數傳給 string 的構造函數。

最后一個構造函數將兩個參數隱式轉換為 string 對象而且它們會被移到 pair 的成員變量 first 和 second 中。

由於這個構造函數有右值引用參數版本,因此任意一個或兩個模板類型參數可以是 unique_ptr<T>。

2.2 復制或移動構造

pair 對象也可以復制或移動構造它的成員變量。例如:

std::pair<std::string, std:: string> new_pair{my_pair}; // Copy constructor

std::pair<std::string, std::string> old_pair{std::make_pair(std::string{"his"},std::string{"hers"})};

old_pair 是由 pair<string,string> 類的移動構造函數生成的。

2.3 復制或移動賦值

不僅成員變量可以被復制和移動,pair 對象也支持復制和移動賦值。例如:

std::pair<std::string, std::string> old_pair; // Default constructor

std::pair<std::string, std::string> new_pair {std::string{"his"} , std::string{"hers"}};

old_pair = new_pair; // Copy assignment

new_pair = std::pair<std::string, std::string> {std::string{"these"}, std::string{"those"}}; // Move assignment

默認的 pair 構造函數會用它的成員變量,即空的 string 對象來生成 old_pair 這是一個空的字符串對象。

第 3 條語句一個成員一個成員地將 new_pair 復制到 old_pair 中。

第 4 條語句將作為賦值運算符的右操作數的 pair 對象的成員變量移到 new_pair 中。

2.4 不同類型成員變量隱式轉換復制賦值

當 pair 對象包含不同類型的成員變量時,也可以將一個 pair 對象賦值給另一個 pair 對象,只要作為右操作數的 pair 對象的成員變量可以隱式轉換為左操作數的 pair 對象的成員變量的類型。

例如:

auto prl = std::make_pair ("these", "those"); // Type pair<const char*, const char*>

std::pair<std::string, std::string> pr2; // Type pair<string, string>

pr2 = prl; // OK in this case

prl 成員變量 first 和 second 的類型是 const char*。這個類型可以隱式轉換為 string,即 pr2 成員變量的類型,因此可以成功賦值。

如果這些類型不能隱式轉換,這條賦值語句就無法通過編譯。

示例

#include <iostream>    // std::cout, std::endl
#include <utility>     // std::pair, std::make_pair
#include <string>    // std::string
 
int main (int argc, char const* argv[]) {
    std::pair<std::string, double> product1 ("tomatoes", 3.25);    // value init
    std::pair<std::string, double> product2;
    std::pair<std::string, double> product3;                // default constructor
    std::pair<std::string, double> product4 (product1);        // copy constructor
     
    product2.first = "lightbulbs";            // the type of first is std::string
    product2.second = 0.99f;                // the type of second is double
     
    product3 = std::make_pair(std::string("shoes"), 20.0);        // using make_pair (move)
     
    std::cout << "The price of " << product1.first << " is $" << product1.second << std::endl; // The price of tomatoes is $3.25
    std::cout << "The price of " << product2.first << " is $" << product2.second << std::endl; // The price of lightbulbs is $0.99
    std::cout << "The price of " << product3.first << " is $" << product3.second << std::endl; // The price of shoes is $20
    std::cout << "The price of " << product4.first << " is $" << product4.second << std::endl; // The price of tomatoes is $3.25

    return 0;
}

3. 其他成員函數及非成員函數操作

3.1 比較操作

pair 對象支持全套的運算符 ==、 !=、 <、 <=、 >、 >=。

當作為操作數的 pair 對象的類型相同並且其成員變量的比較方式也相同時,這些運算符都可以正常使用。

std::pair<std::string, std::string> new_pair;

new_pair.first = "his";

new_pair.second = "hers";

if (new_pair == std::pair<std::string, std::string> {"his", ,"hers"})
    std::cout << "the two pairs equal each other!\n";

new_pair 的成員變量 first 和 second 被賦值為右操作數所包含的字符串。

當兩個 pair 對象相等時,if 語句會輸出一些消息。

當兩個 pair 對象中的任何一個或兩個成員不相等時,!= 比較會返回 true。

對於小於或大於比較,pair 對象的成員變量是按字典順序比較的。

如果 new_pair.first 小於 old_pair.first 的話,表達式 new_pair<old_pair 會返回 true。

如果它們的成員變量 first 相等,但 new_pair.second 小於 old_pair.second,new_pair < old_pair 也為 true。

下面是一個示例:

std::pair<int, int> p1 {10, 9};

std::pair<int, int> p2 {10, 11};

std::pair<int, int> p3 {11, 9};

std::cout<< (p1 < p2 ? "true" : "false") << "\n"
    << (p1 > p3 ? "true" : "false") << "\n"
    << (p3 > p2 ? "true" : "false") << std::endl;

第一個比較的結果為 true,因為 p1 和 p2 的成員變量 first 相等,p1 的成員變量 second 小於 p2 的成員變量 second。

第二個比較的結果為 false,因為 p1 的 first 小於 p3 的 first。

第三個比較的結果則為 true,因為 p3 的 first 大於 p2 的 first。

3.2 交換操作

pair 的成員函數 swap() 可以和作為參數傳入的另一個 pair 對象交換其成員變量 first 和 second。

顯然,參數必須是相同類型。下面有一個示例:

 

std::pair<int, int> p1 {10, 11};

std::pair<int, int> p2 {11, 9};

p1.swap(p2); // p1={ll,9} p2={10/11}

3.3 輔助函數

make_pair<T1,T2> 函數模板是一個輔助函數,可以生成並返回一個 pair<T1,T2> 對象。

auto my_pair = std::make_pair(s1, s2);

auto your_pair = std::make_pair(std::string {"test"},std::string {"that"});

auto his_pair = std::make_pair<std::string, std::string>("test",std::string {"that"});

auto her_pair = std::make_pair<std::string, std::string>("test", "that");

前兩條語句中的函數模板的類型參數由編譯器推斷。

在后兩條語句中,類型是明確的。

如果在這兩條語句中忽略模板類型參數,那么對象類型將是 pair<const char*,string> 和 pair<const char*, const char*>。

4. 應用

結合map的簡單使用

 

std::pair m_pairA;
m_pairA = std::make_pair("sn001", 12.5);

std::map m_mapA;
m_mapA.insert(m_pairA);
std::map::iterator iter = m_mapA.begin();
std::cout << iter->first << "," << iter->second << std::endl;

(全文完)

 


 

參考資料

[1] std::pair

[2] C++ pair(STL pair)類模板的用法詳解

[3] Pair in C++ Standard Template Library (STL)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM