C++ unordered_map 使用詳解(含C++20新特性)

目錄

查找元素

迭代器

容量

修改操作

通接口

哈希策略

觀察器

std::swap(std::unordered_map)

std::erase_if (std::unordered_map)


簡介

本篇博客介紹C++常用的無序關聯容器unordered_mapunordered_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";
    }
}

輸出:
Found

find()的返回值是迭代器,若有元素,可以直接通過返回的迭代器獲取元素信息。 而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 => five
 1 => one
 2 => two
 3 => three
 4 => 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_type
    erase_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();

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章