std::multimap<string, string〉 pets; // Element is pair{pet_type, pet_name} auto iter = pets.insert (std::pair<string, string>{string{"dog"}, string{"Fang"}}); iter = pets.insert(iter, std::make_pair("dog", "Spot")); // Insert Spot before Fang pets.insert(std::make_pair("dog", "Rover"));// Inserts Rover after Fang pets.insert (std::make_pair ("cat", "Korky"));// Inserts Korky before all dogs pets.insert ({{ "rat", "Roland"}, {"pig", "Pinky" }, {"pig", "Perky"}});//Inserts list elements第三條語句的第一個引數是一個作為提示符的疊代器,它說明了元素應該被插入的位置。元素會被立即插入到 iter 所指向元素的前面,因此,這使我們可以覆蓋預設的插入位置。對於預設的插入位置來說,元素會被插入到先前插入的鍵為 "dog" 的元素的後面。元素預設是按照鍵的升序插入的。如果沒有用提示符改變插入位置,有相同鍵的元素的位置和插入位置相同。最後一條語句插入了一些初始化列表中的元素。有高階版本的 insert(),它可以接收兩個疊代器引數,用來指定插入元素的範圍。
auto iter = pets.emplace("rabbit”,"Flopsy"); iter = pets.emplace_hint (iter, "rabbit", "Mopsy");// Create preceding Flopsy這兩個函數都返回一個指向插入元素的疊代器。emplace_hint() 函數盡可能近地在第一個引數所指向位置的前面生成一個新元素。如果只使用 emplace() 來插入 "Mopsy",它可能會被插入到當前所有鍵為 "rabbit" 的元素的後面。
std::multimap<std::string, size_t> people {{"Ann",25},{"Bill", 46}, {"Jack", 77}, {"Jack", 32},{"Jill", 32}, {"Ann", 35} }; std::string name {"Bill"}; auto iter = people.find(name); if (iter ! = std::end (people)) std::cout << name << " is " << iter->second << std::endl; iter = people.find ("Ann"); if (iter != std::end(people)) std::cout << iter->first << " is " << iter->second <<std::endl;如果沒有找到鍵,會返回一個結束疊代器,所以我們應該總是對返回值進行檢查。第一個 find() 呼叫的引數是一個鍵物件,因為這個鍵是存在的,所以輸出語句可以執行。第二個 find() 呼叫的引數是一個字串常數,它說明引數不需要和鍵是相同的型別。對容器來說,可以用任何值或物件作為引數,只要可以用函數物件將它們和鍵進行比較。最後一條輸出語句也可以執行,因為有等於 "Ann" 的鍵。事實上,這裡有兩個等於 "Ann" 的鍵,你可能也會得到不同的執行結果。
auto pr = people.equal_range("Ann"); if(pr.first != std::end(people)) { for (auto iter = pr.first ; iter != pr.second; ++iter) std:cout << iter->first << " is " << iter->second << std::endl; }equal_range() 的引數可以是和鍵同型別的物件,或是不同型別的但可以和鍵比較的物件。返回的 pair 物件的成員變數 first 是一個疊代器,它指向第一個大於等於引數的元素;如果鍵和引數相等的元素存在的話,它是第一個鍵和引數相同的元素。如果鍵不存在,pair 的成員變數 first 就是容器的結束疊代器,所以應該總是對它們進行撿查。
auto iter1 = people.lower_bound("Ann"); auto iter2 = people.lower_bound("Ann"); if(iter1 != std::end(people)) { for(auto iter = iterl ; iter != iter2; ++iter) std::cout << iter->first << " is " << iter->second << std::endl; }它和前一個程式碼段的輸出結果是相同的。通過呼叫 multimap 的成員函數 count() 可以知道有多少個元素的鍵和給定的鍵相同。
auto n = people.count("Jack"); // Returns 2可以用不同的方式使用這些函數。可以選擇 find() 或 equal_range() 來存取元素。如果以班級為鍵,在 mutilmap 中儲存學生資訊,可以用成員函數 count() 來獲取班級的大小。當然,通過將在前面章節介紹的 distance() 函數模板運用到成員函數 equal_range() 返回的疊代器或者 lower_bound() 和 upper_bound() 返回的疊代器上,也可以獲取鍵和給定鍵相等的元素 的個數:
std::string key{"Jack"}; auto n = std::distance( people.lower_bound(key),people.upper_bound(key)); // No. of elements matching key注意,全域性的 equal_range()、lower_bound()、upper_bound() 函數模板的使用方式和關聯容器中同名成員函數的使用方式略有不同。在教學後面的部分你會了解到這些。
// Using a multimap #include <iostream> // For standard streams #include <string> // For string class #include <map> // For multimap container #include <cctype> // For toupper() using std::string; using Pet_type = string; using Pet_name = string; int main() { std::multimap<Pet_type, Pet_name> pets; Pet_type type {}; Pet_name name {}; char more {'Y'}; while(std::toupper(more) == 'Y') { std::cout << "Enter the type of your pet and its name: "; std::cin >> std::ws >> type >> name; // Add element - duplicates will be LIFO auto iter = pets.lower_bound(type); if(iter != std::end(pets)) pets.emplace_hint(iter, type, name); else pets.emplace(type, name); std::cout << "Do you want to enter another(Y or N)? "; std::cin >> more; } // Output all the pets std::cout << "nPet list by type:n"; auto iter = std::begin(pets); while(iter != std::end(pets)) { auto pr = pets.equal_range(iter->first); std::cout << "nPets of type " << iter->first << " are:n"; for(auto p = pr.first; p != pr.second; ++p) std::cout << " " << p->second; std::cout << std::endl; iter = pr.second; } }我們在程式碼中使用一些型別別名將型別及其表示的事物關聯了起來。pets 容器儲存的是 pair<string,string> 型別的物件,這個 pair 物件以 pet 型別作為鍵,以 pet 的名稱為物件。
Enter the type of your pet and its name: rabbit Flopsy
Do you want to enter another(Y or N)? y
Enter the type of your pet and its name: rabbit Mopsy
Do you want to enter another(Y or N)? y
Enter the type of your pet and its name: rabbit Cottontail
Do you want to enter another(Y or N)? y
Enter the type of your pet and its name: dog Rover
Do you want to enter another(Y or N)? y
Enter the type of your pet and its name: dog Spot
Do you want to enter another(Y or N)? y
Enter the type of your pet and its name: snake Slither
Do you want to enter another(Y or N)? y
Enter the type of your pet and its name: snake Sammy
Do you want to enter another(Y or N)? n
Pet list by type:
Pets of type dog are:
Spot Rover
Pets of type rabbit are:
Cottontail Mopsy Flopsy
Pets of type snake are:
Sammy Slither