std::pair 是一個結構體模板,其可於一個單元內存儲兩個相異對象。是 std::tuple 的擁有兩個元素的特殊狀況。html
通常來講,pair 能夠封裝任意類型的對象,能夠生成各類不一樣的 std::pair<T1, T2> 對象,能夠是數組對象或者包含 std::pair<T1,T2> 的 vector 容器。pair 還能夠封裝兩個序列容器或兩個序列容器的指針。ios
1. 定義數組
#include <utility> template<class T1, class T2> struct pair;模板參數 T1 和 T2 是 pair 所存儲的元素的類型。函數
包含有兩個成員變量 first 和 second,並且都是 public 修飾的,經過 "." 訪問。this
其中 first 類型爲T1, second 類型爲T2。spa
(constructor) constructs new pair (public member function) operator= assigns the contents (public member function) swap swaps the contents (public member function)
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. 初始化.net
初始化一個 pair 可使用構造函數,也可使用 std::make_pair。指針
make_pair 定義以下:code
template<class T1, class T2> std::pair make_pair(T1 a, T2 b) { return std::pair(a, b); }
2.1 默認構造htm
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 caseprl 成員變量 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