map 類別範本有 4 個型別引數,但一般只需要指定前兩個模板引數的值。第 1 個是鍵的型別,第 2 個是所儲存物件的型別,第 3 個和第 4 個模板引數分別定義了用來比較鍵的函數物件的型別以及為 map 分配記憶體的物件的型別。最後兩個引數有預設值。在本節稍後部分會展示如何定義不同型別的比較鍵的函數物件,但不會定義可替代的分配器型別。
map<> 容器類的預設建構函式會建立一個空的 map 容器。例如,可以建立一個這樣的容器,size_t 型別的值表示年齡,作為它儲存的值,string 型別的值表示名稱,作為它的鍵:
std::map<std::string, size_t> people;
第 1 個模板型別引數指定鍵的型別是字串,第 2 個模板型別引數指定值的型別為 size_t。當然,這裡的模板型別引數可以是任何型別,唯一的要求是鍵必須可以用 less<K> 比或用自己指定的另一個函數物件來替代。
map<K,T> 中的每個元素都是同時封裝了物件及其鍵的 pair<const K,T> 型別物件,這裡不能修改 const K。pair<T1,T2> 類的模板定義在 utility 標頭檔案中,它被包含在 map 標頭檔案中。因此 people 容器中的元素是 pair<const string,size_t> 型別的。pair<T1,T2> 這種模板型別並不是專門在這種情況下使用的。必要時可以用它將兩個不同型別的物件組裝成一個物件。本章稍後將講解更多這方面的內容。
我們可以用初始化列表來指定 map 的初始值,但因為 map 中包含的是 pair<const K,T> 型別的元素,所以初始化列表中的值也必須是這種型別。下面展示了如何為 people 容器設定初始值:
std::map<std::string, size_t> people{{"Ann", 25}, {"Bill", 46},{"Jack", 32},{"Jill", 32}};
初始化列表中的值是通過將每個巢狀花括號中的兩個值傳遞給建構函式產生的,因此列表會包含 4 個 pair<const string,size_t> 物件。
utility 標頭檔案中定義了 make_pair < T1,T2 >() 函數模板,它提供了一種組合 T1 和 T2 型別物件的簡單方法。因此,可以按如下方式建立 pair 物件來初始化 map:
std::map<std::string,size_t> people{std::make_pair("Ann",25),std::make_pair("Bill", 46),std::make_pair("Jack", 32),std::make_pair("Jill", 32)};
make_pair<T1,T2>() 函數模板從函數引數中推斷出型別引數值,因而由參數列中呼叫 make_pair<>() 返回的是 <char const*,int> 型別的物件。因為這些物件都是 map 容器 people 的初始值,所以這些 pair 物件會被轉換成 map 中元素的型別,即 pair<const string,size_t>。
pair<T1, T2> 的公共成員變數 first 和 second 分別儲存了儲存 T1 和 T2 型別的物件。只要原始 pair 物件的成員變數 first 和 second 可以隱式轉換為與目標 pair 物件成員變數相同型別的變數,pair<T1;T2> 模板的建構函式就可以提供這種型別的隱式轉換。
map<K,T> 模板定義了移動和複製建構函式,所以可以複製現有的容器。例如:
std::map<std::string, size_t> personnel {people}; // Duplicate people map
map 容器 personnel 包含 people 元素的副本。
可以用另一個容器的一段元素來建立一個 map,用開始和結束疊代器以通常的方式指定元素。顯然,疊代器指向的 pair 元素的型別必須和容器相容。這裡有一個範例:
std::map<std::string, size_t> personnel {std::begin(people),std::end(people)};
這樣就生成了 personnel,並且用 people 容器的疊代器指定的元素對它進行了初始化。map 容器提供了雙向疊代器,這樣就可以通過自增或自減存取元素。map 容器還提供了反向疊代器,所以可以從最後一個元素遍歷到第一個元素。personnel 容器包含的元素和 people 完全相同。當然,也可以用另一個容器的元素子集來建立容器:
std::map<std::string,size_t> personnel {++std::begin(people),std::end(people)};