C++ unordered_map 使用详解(含C++20新特性)
目錄
查找元素
迭代器
容量
修改操作
通接口
哈希策略
觀察器
std::swap(std::unordered_map)
std::erase_if?(std::unordered_map)
簡介
本篇博客介紹C++常用的無序關聯容器unordered_map。unordered_map是C++11正式加入的對hash_map的官方實現(之前標準C++沒有hash_map的官方實現,我們使用的STL的hash_map并不是官方的)。從名字可以看出這個結構是無序的,底層設計思想和STL的hash_map一樣。元素在內部不以任何特定順序排序,而是放進桶中。元素放進哪個桶完全依賴于其鍵的哈希。這允許對單獨元素的快速訪問,因為一旦計算哈希,則它準確指代元素所放進的桶。unordered_map搜索、插入和元素移除擁有平均常數時間復雜度。
?
查找元素
at()用于訪問指定元素
T&?at(?const?Key&?key?); const?T&?at(?const?Key&?key?)?const;返回到等于?key?的鍵的元素的引用。若無該元素,則拋出 std::out_of_range?類型異常。
?
operator []用于訪問或插入元素
T&?operator[](?const?Key&?key?); T&?operator[](?Key&&?key?);返回等于?key?的鍵的值的引用。如果該鍵不存在,則執行插入,反之,則覆蓋原來的值。
#include <iostream> #include <string> #include <vector> #include <unordered_map>int main() {std::unordered_map<char, int> letter_counts {{'a', 27}, {'b', 3}, {'c', 1}};std::cout << "initially:\n";for (const auto &pair : letter_counts) {std::cout << pair.first << ": " << pair.second << '\n';}letter_counts['b'] = 42; // 更新既存值letter_counts['x'] = 9; // 插入新值std::cout << "after modifications:\n";for (const auto &pair : letter_counts) {std::cout << pair.first << ": " << pair.second << '\n';}// 統計每個詞的出現數// (首次調用 operator[] 以零初始化計數器)std::unordered_map<std::string, size_t> word_map;for (const auto &w : { "this", "sentence", "is", "not", "a", "sentence","this", "sentence", "is", "a", "hoax"}) {++word_map[w];}for (const auto &pair : word_map) {std::cout << pair.second << " occurrences of word '" << pair.first << "'\n";} }輸出: initially: a: 27 b: 3 c: 1 after modifications: a: 27 b: 42 c: 1 x: 9 2 occurrences of word 'a' 1 occurrences of word 'hoax' 2 occurrences of word 'is' 1 occurrences of word 'not' 3 occurrences of word 'sentence' 2 occurrences of word 'this'?
count() 返回特定鍵的元素數量
(1)size_type count(?const?Key&?key?)?const; (2)template<?class?K?>?size_type count(?const?K&?x?)?const;(1)?返回等于指定參數?key?的鍵的元素數,因為此容器不允許重復,故返回值為 0?或 1?。
(2)?返回鍵等于指定參數?x?的元素數。此重載僅若有限定標識?Hash::is_transparent?與?KeyEqual::is_transparent?均合法并指代類型才參與重載決議。這假設能用?K?和?Key?類型一起調用這種?Hash?,還有?KeyEqual?是通透的,進而允許不用構造?Key?的實例就調用此函數。
?
find()尋找特定鍵的元素
(1)iterator find(?const?Key&?key?); (2)const_iterator find(?const?Key&?key?)?const; (3)template<?class?K?>?iterator find(?const?K&?x?); (4)template<?class?K?>?const_iterator find(?const?K&?x?)?const;(1-2)?尋找鍵等于?key?的的元素。
(3-4)?尋找鍵等于值?x?的元素。此重載僅若有限定標識?Hash::is_transparent?與?KeyEqual::is_transparent?均合法并指代類型才參與重載決議。這假設能用?K?和?Key?類型一起調用這種?Hash?,還有?KeyEqual?是通透的,進而允許不用構造?Key?的實例就調用此函數。
#include <iostream> #include <unordered_map>int main() { // 簡單比較演示std::unordered_map<int,char> example = {{1,'a'},{2,'b'}};auto search = example.find(2);if (search != example.end()) {std::cout << "Found " << search->first << " " << search->second << '\n';} else {std::cout << "Not found\n";} }輸出: Found 2 b?
contains()可檢查容器是否含有特定鍵的元素
(1)bool?contains(?const?Key&?key?)?const; (2)template<?class?K?>?bool?contains(?const?K&?x?)?const;(1)?檢查容器中是否有鍵等于?key?的元素。
(2)?檢查是否有鍵等于值?x?的元素。此重載僅若有限定標識?Hash::is_transparent?與?KeyEqual::is_transparent?均合法并指代類型才參與重載決議。這假設能用?K?和?Key?類型一起調用這種?Hash?,還有?KeyEqual?是通透的,進而允許不用構造?Key?的實例就調用此函數。
#include <iostream> #include <unordered_map>int main() { std::unordered_map<int,char> example = {{1,'a'},{2,'b'}};if (example.contains(2)) {std::cout << "Found\n";} else {std::cout << "Not found\n";} }輸出: Foundfind()的返回值是迭代器,若有元素,可以直接通過返回的迭代器獲取元素信息。 而contains()的返回值是bool型,只用于確定是否包含該元素。
?
equal_range()返回匹配特定鍵的元素范圍
(1)std::pair<iterator,iterator>?equal_range(?const?Key&?key?); (2)std::pair<const_iterator,const_iterator>?equal_range(?const?Key&?key?)?const; (3)template<?class?K?>std::pair<iterator,iterator>?equal_range(?const?K&?x?); (4)template<?class?K?>std::pair<const_iterator,const_iterator>?equal_range(?const?K&?x?)?const;(1-2)?返回容器中所有鍵等于?key?的元素范圍。范圍以兩個迭代器定義,第一個指向所需范圍的首元素,而第二個指向范圍的尾后一位元素。
(3-4)?返回含有容器中所有鍵等于?x?的元素的范圍。此重載僅若有限定標識?Hash::is_transparent?與?KeyEqual::is_transparent?均合法并指代類型才參與重載決議。這假設能用?K?和?Key?類型一起調用這種?Hash?,還有?KeyEqual?是通透的,進而允許不用構造?Key?的實例就調用此函數。
#include <iostream> #include <unordered_map>int main() { std::unordered_map<int,char> map = {{1,'a'},{1,'b'},{1,'d'},{2,'b'}};auto range = map.equal_range(1);for (auto it = range.first; it != range.second; ++it) {std::cout << it->first << ' ' << it->second << '\n';} }輸出: 1 a?
迭代器
begin() & cbegine()
iterator begin()?noexcept; const_iterator begin()?const?noexcept; const_iterator cbegin()?const?noexcept;返回指向?unordered_map?首元素的迭代器。若?unordered_map?為空,則返回的迭代器將等于 end()。
?
end() & cend()
iterator end()?noexcept; const_iterator end()?const?noexcept; const_iterator cend()?const?noexcept;返回指向?unordered_map?最后一個元素的之后的迭代器。此元素表現為占位符;試圖訪問它導致未定義行為。
#include <cmath> #include <iostream> #include <unordered_map>struct Node { double x, y; };int main() {Node nodes[3] = { {1, 0}, {2, 0}, {3, 0} };// mag 是將 Node 的地址映射到其在平面中的模的映射std::unordered_map<Node *, double> mag = {{ nodes, 1 },{ nodes + 1, 2 },{ nodes + 2, 3 }};// 將每個 y 坐標從 0 更改到模for(auto iter = mag.begin(); iter != mag.end(); ++iter){auto cur = iter->first; // 指向 Node 的指針cur->y = mag[cur]; // 可以也使用 cur->y = iter->second;}// 更新并打印每個結點的模for(auto iter = mag.begin(); iter != mag.end(); ++iter){auto cur = iter->first;mag[cur] = std::hypot(cur->x, cur->y);std::cout << "The magnitude of (" << cur->x << ", " << cur->y << ") is ";std::cout << iter->second << '\n';}// 以基于范圍的 for 循環重復上述者for(auto i : mag) {auto cur = i.first;cur->y = i.second;mag[cur] = std::hypot(cur->x, cur->y);std::cout << "The magnitude of (" << cur->x << ", " << cur->y << ") is ";std::cout << mag[cur] << '\n';// 注意與 std::cout << iter->second << '\n'; 相反,上述的 // std::cout << i.second << '\n'; 不會打印更新的模} }輸出: The magnitude of (1, 1) is 1.41421 The magnitude of (2, 2) is 2.82843 The magnitude of (3, 3) is 4.24264 The magnitude of (1, 1.41421) is 1.73205 The magnitude of (2, 2.82843) is 3.4641 The magnitude of (3, 4.24264) is 5.19615?
容量
empty() 用于檢查容器是否為空
bool?empty()?const?noexcept; [[nodiscard]]?bool?empty()?const?noexcept;?
size() 返回容納的元素數量
size_type size()?const?noexcept;返回容器中的元素數,即std::distance(begin(), end())?。
int main() { std::unordered_map<int,char> nums {{1, 'a'}, {3, 'b'}, {5, 'c'}, {7, 'd'}};std::cout << "nums contains " << nums.size() << " elements.\n"; }輸出: nums contains 4 elements.?
max_size() 返回最大可容納的元素數
size_type max_size()?const?noexcept;返回根據系統或庫實現限制的容器可包含的元素最大數量,即對于最大容器的 std::distance(begin(), end())??。
#include <iostream> #include <unordered_map>int main() {std::unordered_map<char,char> s;std::cout << "Maximum size of a 'unordered_map' is " << s.max_size() << "\n"; }輸出: Maximum size of a 'unordered_map' is 768614336404564650?
修改操作
clear()
void?clear()?noexcept;從容器去除所有元素。此調用后?size()?返回零。非法化任何指代所含元素的引用、指針或迭代器。可能亦非法化尾后迭代器。
?
insert()
(1)std::pair<iterator,bool>?insert(?const?value_type&?value?);std::pair<iterator,bool>?insert(?value_type&&?value?); (2)template<?class?P?>std::pair<iterator,bool>?insert(?P&&?value?); (3)iterator insert(?const_iterator hint,?const?value_type&?value?);iterator insert(?const_iterator hint, value_type&&?value?); (4)template<?class?P?>iterator insert(?const_iterator hint, P&&?value?); (5)template<?class?InputIt?>void?insert(?InputIt first, InputIt last?); (6)void?insert(?std::initializer_list<value_type>?ilist?); (7)insert_return_type insert(node_type&&?nh); (8)iterator insert(const_iterator hint, node_type&&?nh);若容器尚未含有帶等價關鍵的元素,則插入元素到容器中。
(1-2)?插入?value?。重載?(2)?等價于?emplace(std::forward<P>(value))?,且僅若?std::is_constructible<value_type, P&&>::value?==?true?才參與重載決議。
(3-4)?插入?value?,以?hint?為應當開始搜索的位置的非強制建議。重載?(4)?等價于?emplace_hint(hint,?std::forward<P>(value))?,且僅若?std::is_constructible<value_type, P&&>::value?==?true?才參與重載決議。
(5)?插入來自范圍?[first, last)?的元素。若范圍中的多個元素擁有比較等價的關鍵,則插入哪個元素是未指定的。
(6)?插入來自 initializer_list?ilist?的元素。若范圍中的多個元素擁有比較等價的關鍵,則插入哪個元素是未指定的。
(7)?若?nh?是空的結點句柄,則不做任何事。否則插入?nh?所占有的元素到容器,若容器尚未含有擁有等價于?nh.key()?的關鍵的元素。若?nh?非空且?get_allocator()?!=?nh.get_allocator()?則行為未定義。
(8)?若?nh?是空的結點句柄,則不做任何事并返回尾迭代器。否則,插入?nh?所占有的元素到容器,若容器尚未含有擁有等價于?nh.key()?的關鍵的元素,并返回指向擁有等于?nh.key()?的關鍵的元素的迭代器(無關乎插入成功還是失敗)。若插入成功,則從?nh?移動,否則它保持該元素的所有權。元素被插入到盡可能接近?hint?的位置。若?nh?非空且?get_allocator()?!=?nh.get_allocator()?則行為未定義。
若因插入發生重哈希,則所有迭代器都被非法化。否則迭代器不受影響。引用不受影響。重哈希僅若新元素數量大于?max_load_factor()*bucket_count()?才發生。若插入成功,則在結點把柄保有元素時獲得的指向該元素的指針和引用被非法化,而在提取前獲得的指向元素的指針和引用變得合法。?
#include <string> #include <iostream> #include <unordered_map>int main () {std::unordered_map<int, std::string> dict = {{1, "one"}, {2, "two"}};dict.insert({3, "three"});dict.insert(std::make_pair(4, "four"));dict.insert({{4, "another four"}, {5, "five"}});bool ok = dict.insert({1, "another one"}).second;std::cout << "inserting 1 -> \"another one\" " << (ok ? "succeeded" : "failed") << '\n';std::cout << "contents:\n";for(auto& p: dict)std::cout << " " << p.first << " => " << p.second << '\n'; }輸出: inserting 1 -> "another one" failed contents:5 => five1 => one2 => two3 => three4 => four?
insert_or_assign()
(1)template?<class?M>pair<iterator,?bool>?insert_or_assign(const?key_type&?k, M&&?obj); (2)template?<class?M>pair<iterator,?bool>?insert_or_assign(key_type&&?k, M&&?obj); (3)template?<class?M>iterator insert_or_assign(const_iterator hint,?const?key_type&?k, M&&?obj); (4)template?<class?M>iterator insert_or_assign(const_iterator hint, key_type&&?k, M&&?obj);(1,3)?若等價于?k?的鍵已存在于容器中,則賦值?std::forward<M>(obj)?給對應于鍵?k?的?mapped_type?。若鍵不存在,則如同用?insert?插入從?value_type(k,?std::forward<M>(obj))?構造的新值。
(2,4)?同?(1,3)?,除了從?value_type(std::move(k),?std::forward<M>(obj))?構造被映射值。
若插入發生且導致容器的重哈希,則所有迭代器被非法化。否則迭代器不受影響。重哈希僅若新元素數量大于?max_load_factor()*bucket_count()?才發生。
#include <iostream> #include <unordered_map> #include <string>int main() {std::unordered_map<std::string, std::string> myMap;myMap.insert_or_assign("a", "apple" );myMap.insert_or_assign("b", "bannana" );myMap.insert_or_assign("c", "cherry" );myMap.insert_or_assign("c", "clementine");for (const auto &pair : myMap) {std::cout << pair.first << " : " << pair.second << '\n';} }輸出: c : clementine a : apple b : bannana?
emplace()
template<?class...?Args?> std::pair<iterator,bool>?emplace(?Args&&...?args?);若容器中無擁有該關鍵的元素,則插入以給定的?args?原位構造的新元素到容器。
細心地使用?emplace?允許在構造新元素的同時避免不必要的復制或移動操作。 準確地以與提供給?emplace?者相同的參數,通過std::forward<Args>(args)...?轉發調用新元素(即?std::pair<const?Key, T>?)的構造函數。 即使容器中已有擁有該關鍵的元素,也可能構造元素,該情況下新構造的元素將被立即銷毀。
若因插入發生重哈希,則所有迭代器都被非法化。否則迭代器不受影響。引用不被非法化。重哈希僅若新元素數量大于?max_load_factor()*bucket_count()?才發生。
#include <iostream> #include <utility> #include <string> #include <unordered_map>int main() {std::unordered_map<std::string, std::string> m;// 使用 pair 的移動構造函數m.emplace(std::make_pair(std::string("a"), std::string("a")));// 使用 pair 的轉換移動構造函數m.emplace(std::make_pair("b", "abcd"));// 使用 pair 的模板構造函數m.emplace("d", "ddd");// 使用 pair 的逐片構造函數m.emplace(std::piecewise_construct,std::forward_as_tuple("c"),std::forward_as_tuple(10, 'c'));// C++17 起,能使用 m.try_emplace("c", 10, 'c');for (const auto &p : m) {std::cout << p.first << " => " << p.second << '\n';} }輸出: a => a b => abcd c => cccccccccc d => ddd #include <unordered_map> #include <iostream> #include <utility>int main() {std::unordered_map<int, int> numbers;std::cout << "Initially, numbers.empty(): " << numbers.empty() << '\n';numbers.emplace(42, 13);numbers.insert(std::make_pair(13317, 123)); std::cout << "After adding elements, numbers.empty(): " << numbers.empty() << '\n'; }輸出: Initially, numbers.empty(): 1 After adding elements, numbers.empty(): 0?
emplace_hint()
template?<class...?Args> iterator emplace_hint(?const_iterator hint, Args&&...?args?);插入新元素到容器,以?hint?為應當放置新元素位置的建議。原位構造元素,即不進行復制或移動操作。
準確地以與提供給函數者相同的參數,以?std::forward<Args>(args)...?轉發調用元素類型(?value_type?即?std::pair<const?Key, T>?)的構造函數。
若因插入發生重哈希,則所有迭代器都被非法化。否則迭代器不受影響。引用不被非法化。重哈希僅若新元素數量大于?max_load_factor()*bucket_count()?才發生。
?
try_emplace()
(1)template?<class...?Args>pair<iterator,?bool>?try_emplace(const?key_type&?k, Args&&...?args); (2)template?<class...?Args>pair<iterator,?bool>?try_emplace(key_type&&?k, Args&&...?args); (3)template?<class...?Args>iterator try_emplace(const_iterator hint,?const?key_type&?k, Args&&...?args); (4)template?<class...?Args>iterator try_emplace(const_iterator hint, key_type&&?k, Args&&...?args);(1)?若容器中已存在等價于?k?的關鍵,則不做任何事。否則行為類似?emplace?,除了以?value_type(std::piecewise_construct, std::forward_as_tuple(k), std::forward_as_tuple(std::forward<Args>(args)...))?構造元素。
(2)?若容器中已存在等價于?k?的關鍵,則不做任何事。否則行為類似?emplace?,除了以?value_type(std::piecewise_construct, std::forward_as_tuple(std::move(k)), std::forward_as_tuple(std::forward<Args>(args)...))?構造元素。
(3)?若容器中已存在等價于?k?的關鍵,則不做任何事。否則行為類似?emplace_hint?,除了以?value_type(std::piecewise_construct, std::forward_as_tuple(k), std::forward_as_tuple(std::forward<Args>(args)...))?構造元素。
(4)?若容器中已存在等價于?k?的關鍵,則不做任何事。否則行為類似?emplace_hint?,除了以?value_type(std::piecewise_construct, std::forward_as_tuple(std::move(k)), std::forward_as_tuple(std::forward<Args>(args)...))?構造元素。
若因插入發生重哈希,則所有迭代器都被非法化。否則迭代器不受影響。引用不被非法化。重哈希僅若新元素數量大于?max_load_factor()*bucket_count()?才發生。
#include <iostream> #include <utility> #include <string>#include <unordered_map> int main() {using namespace std::literals;std::unordered_map<std::string, std::string> m;m.try_emplace("a", "a"s);m.try_emplace("b", "abcd");m.try_emplace("c", 10, 'c');m.try_emplace("c", "Won't be inserted");for (const auto &p : m) {std::cout << p.first << " => " << p.second << '\n';} }輸出: a => a b => abcd c => cccccccccc?
erase()
(1)iterator erase(?const_iterator pos?); (2)iterator erase(?const_iterator first, const_iterator last?); (3)size_type erase(?const?key_type&?key?);從容器移除指定的元素。
(1)?移除位于?pos?的元素。
(2)?移除范圍?[first; last)?中的元素,它必須是?*this?中的合法范圍。
(3)?移除鍵等于?key?的元素(若存在一個)。
到被去除元素的引用和迭代器被非法化,其他迭代器和引用不被非法化。迭代器?pos?必須合法且可解引用,從而使得?end()?迭代器(合法,但不可解引用)不能用作?pos?所用的值。保留未被擦除的元素順序(這使得可能在迭代通過容器時擦除單獨的元素)。
#include <unordered_map> #include <iostream> int main() {std::unordered_map<int, std::string> c = {{1, "one"}, {2, "two"}, {3, "three"},{4, "four"}, {5, "five"}, {6, "six"}};// 從 c 擦除所有奇數for(auto it = c.begin(); it != c.end(); )if(it->first % 2 == 1)it = c.erase(it);else++it;for(auto& p : c)std::cout << p.second << ' '; }輸出: two four six?
swap()
void?swap(?unordered_map&?other?); void?swap(?unordered_map&?other?)?noexcept();將內容與?other?的交換,不在單個元素上調用任何移動、復制或交換操作。所有迭代器和引用保持合法,尾后迭代器被非法化。
Hash?和?KeyEqual?對象必須可交換?(Swappable)?,并用非成員?swap?的非限定調用交換它們。
?
extract()
(1)node_type extract(?const_iterator position?); (2)node_type extract(?const?key_type&?x?);(1)?解鏈含?position?所指向元素的結點并返回占有它的結點句柄。
(2)?若容器擁有元素而其關鍵等于?x?,則從容器解鏈該元素并返回占有它的結點句柄。否則,返回空結點把柄。任何情況下,均不復制或移動元素,只重指向容器結點的內部指針。
釋出結點只會非法化指向被釋出元素的迭代器,并保持未被去除元素的相對順序。指向被釋出元素的指針和引用保持合法,但在結點句柄占有該元素時不能使用:若元素被插入容器,就能使用它們。
注意:extract 是更換鍵而不重分配的唯一方式。
unordered_map<int, string> m{{1, "mango"}, {2, "papaya"}, {3, "guava"}}; auto nh = m.extract(2); nh.key() = 4; m.insert(move(nh));?
merge()
(1)template<class?H2,?class?P2>void?merge(std::unordered_map<Key, T, H2, P2, Allocator>&?source); (2)template<class?H2,?class?P2>void?merge(std::unordered_map<Key, T, H2, P2, Allocator>&&?source); (3)template<class?H2,?class?P2>void?merge(std::unordered_multimap<Key, T, H2, P2, Allocator>&?source); (4)template<class?H2,?class?P2>void?merge(std::unordered_multimap<Key, T, H2, P2, Allocator>&&?source);試圖釋出("接合")?source?中每個元素,并用?*this?的哈希函數和關鍵相等謂詞插入到?*this?。 若?*this?中有元素,其關鍵等價于來自?source?中元素的關鍵,則不從?source?釋出該元素。 不復制或移動元素,只會重指向容器結點的內部指針。指向被轉移元素的所有指針和引用保持合法,但現在指代到?*this?中而非到?source?中。指代被轉移元素的迭代器和所有指代到?*this?的迭代器被非法化。指向留在?source?中元素的迭代器保持合法。若?get_allocator()?!=?source.get_allocator()?則行為未定義。
?
通接口
begin()?& cbegin()
local_iterator begin(?size_type n?); const_local_iterator begin(?size_type n?)?const; const_local_iterator cbegin(?size_type n?)?const;返回指向下標為?n?的桶首元素的迭代器。
?
end() & cend()
local_iterator end(?size_type n?); const_local_iterator end(?size_type n?)?const; const_local_iterator cend(?size_type n?)?const;返回后隨下標為?n?的桶的最后元素的元素的迭代器。此元素表現為占位符,試圖訪問它會導致未定義行為。
?
bucket_count()?返回容器中的桶數
size_type bucket_count()?const;?
max_bucket_count()?返回容器由于系統或庫實現限制的能保有的最大桶數
size_type max_bucket_count()?const;?
bucket_size()?返回下標為?n?的桶中的元素數
size_type bucket_size(?size_type n?)?const;?
bucket()?返回關鍵?key?的桶的下標
size_type bucket(?const?Key&?key?)?const;始終會在此桶中找到關鍵等于?key?的元素(若存在)。返回值僅對?bucket_count()?返回相同值的容器實例合法。若?bucket_count()?為零則行為未定義。
?
哈希策略
load_factor()?
float?load_factor()?const;返回每個桶元素的平均數,即?size()?除以?bucket_count()?。
?
max_load_factor()
(1)float?max_load_factor()?const; (2)void?max_load_factor(?float?ml?);管理最大加載因子(每個桶的平均元素數)。若加載因子超出此閾值,則容器自動增加桶數。
(1) 返回最大加載因子。
(2) 設置最大加載因子為?ml?。
?
rehash()
void?rehash(?size_type count?);設置桶數為?count?并重哈希容器,即考慮桶總數已改變,再把元素放到適當的桶中。若新的桶數使加載因子大于最大加載因子(?count?<?size()?/?max_load_factor()?),則新桶數至少為?size()?/?max_load_factor()?。
?
reserve()
void?reserve(?size_type count?);設置桶數為適應至少?count?個元素,而不超出最大加載因子所需的數,并重哈希容器,即考慮桶數已更改后將元素放進適合的桶。等效地調用?rehash(std::ceil(count?/?max_load_factor()))?。
?
觀察器
hash_function()?返回對關鍵哈希的函數
hasher hash_function()?const;?
key_eq()?返回比較關鍵相等性的函數
key_equal key_eq()?const;?
std::swap(std::unordered_map)
(1)template<?class?Key,?class?T,?class?Hash,?class?KeyEqual,?class?Alloc?>void?swap(?unordered_map<Key,T,Hash,KeyEqual,Alloc>&?lhs,?unordered_map<Key,T,Hash,KeyEqual,Alloc>&?rhs?); (2)template<?class?Key,?class?T,?class?Hash,?class?KeyEqual,?class?Alloc?>void?swap(?unordered_map<Key,T,Hash,KeyEqual,Alloc>&?lhs,?unordered_map<Key,T,Hash,KeyEqual,Alloc>&?rhs?)?noexcept(/* see below */);為?std::unordered_map?特化?std::swap?算法。交換?lhs?與?rhs?的內容。調用?lhs.swap(rhs)?。
?
std::erase_if?(std::unordered_map)
template<?class?Key,?class?T,?class?Hash,?class?KeyEqual,?class?Alloc,?class?Pred?> typename?std::unordered_map<Key,T,Hash,KeyEqual,Alloc>::size_typeerase_if(std::unordered_map<Key,T,Hash,KeyEqual,Alloc>&?c, Pred pred);? ?(C++20 起)從容器中去除所有滿足謂詞?pred?的元素。等價于:
auto old_size = c.size();for (auto i = c.begin(), last = c.end(); i != last; ) {if (pred(*i)) {i = c.erase(i);} else {++i;}} return old_size - c.size();?
總結
以上是生活随笔為你收集整理的C++ unordered_map 使用详解(含C++20新特性)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++实现字符串分割函数split()
- 下一篇: C++ 动态二维数组(二维vector)