11-2 關聯容器概述
阿新 • • 發佈:2022-02-27
目錄
11.2.1 定義關聯容器
//宣告空容器 map<string, size_t> word_count; //列表初始化 set<string> exclude = {"the","and","or"}; map<string, string> authors = { {"John","James"}, {"Asten","Jane"}, {"Dikens","Charles"}};
初始化multimap或multiset
int main(){ //定義一個有20個元素的vector,儲存0到9每個整數的兩個拷貝 vector<int> ivec; for (vector<int>::size_type i = 0; i != 10; ++i){ ivec.push_back (i) ; ivec.push_back(i); //每個數重複儲存一次 } //iset包含來自ivec的不重複的元素;miset包含所有20個元素 set<int> iset(ivec.cbegin(), ivec.cend()) ; multiset<int> miset(ivec.cbegin(), ivec.cend()); cout<< ivec.size () << endl; //打印出20 cout<< iset.size ( ) <<endl; //打印出 10 cout << miset.size () <<endl;//打印出20 return 0; }
11.2.2 關鍵字型別的要求
對於有序容器map,multimap,set,multiset,關鍵字型別必須定義元素比較的方法
傳遞給排序演算法的可呼叫物件(參見10.3.1節,第344頁)必須滿足與關聯容器中關鍵字一樣的型別要求
有序容器的關鍵字型別
可以向一個演算法提供我們自己定義的比較操作(參見10.3節,第344頁),與之類似,也可以提供自己定義的操作來代替關鍵字上的<運算子。
所提供的操作必須在關鍵字型別上定義一個嚴格弱序(strict weak ordering)。可以將嚴格弱序看作“小於等於”,雖然實際定義的操作可能是一個複雜的函式。無論我們怎樣定義比較函式,它必須具備如下基本性質:
- 兩個關鍵字不能同時“小於等於”對方;如果k1“小於等於”k2,那麼k2絕不能“小於等於”k1。
- 如果 k1“小於等於”k2,且k2“小於等於”k3,那麼k1必須“小於等於”k3。
- 如果存在兩個關鍵字,任何一個都不“小於等於”另一個,那麼我們稱這兩個關鍵字是“等價”的。如果k1“等價於”k2,且k2“等價於”k3,那麼k1必須“等價於”k3。
在實際程式設計中,我們考慮的是一個型別是否定義了“行為正常”的<運算子,只要定義了,它就可以用作關鍵字型別
使用關鍵字型別的比較函式
假設一個類型別Sale_data未定義‘<’,此時我們可以自己定義一個比較函式傳給map,來建立一個Sale_data的map【否則無法建立】
//依照isbn排序
bool compareIsbn(const Sale_data &lhs, const Sale_data &rhs){
return lhs.isbn()<rhs.isbn();
}
建立Sale_data的map:
//bookstore中多條記錄可以有相同的isbn
//bookstore中的元素以isbn順序進行排序
multiset<Sale_data, decltype(compareIsbn)*>
bookstore(compareIsbn);
模板接受兩個引數,一個指定元素型別,一個函式指標
宣告時傳入函式指標compareIsbn
注:和陣列名錶示一個指標類似,函式名就代表函式指標
11.2.3 pair型別
宣告和初始化
定義在標頭檔案utility
中
有兩個資料成員first和second,必須提供兩個型別引數
pair<string, string> anon; //儲存兩個string
pair<string, size_t> word_count; //一個string一個size_t
可以在宣告時直接初始化first和second成員:
pair<int, int> i_to_i{1,2};
cout<<i_to_i.first<<" "<<i_to_i.second<<endl;
//輸出:1 2
支援的操作
建立pair物件的函式
函式可以返回pair物件
pair<string, int> process(vector<string> &v){
if(!v.empty())
return
//構造一個pair並返回其拷貝
pair<string, int>(v.back(), v.back().size());
else
//構造空pair並返回其拷貝
return pair<string, int>();
}
除了直接定義外,還可以用make_pair來生成pair物件:
if(!v.empty())
return make_pair(v.back(), v.back().size());
新標準允許在返回pair時直接進行列表初始化:
if(!v.empty())
return {v.back(), v.back().size()};