C unordered map初始化詳解

2021-09-24 15:06:45 字數 2184 閱讀 6139

生成 unordered_map 容器和生成 map 一樣簡單,只要可以用 hash的例項雜湊 k 型別的鍵,而且必須能夠用 == 運算子來比較鍵。下面展示了如何定義和初始化 unordered_map:

std::unordered_mappeople , , }; // name,age

這樣就生成了乙個包含 pair元素的容器,並用初始化列表中的元素對它進行了初始化。容器中格仔的個數是預設的,它使用 equal_to() 物件來判斷鍵是否相等。它會用定義在 string 標頭檔案中的 hash來對 string 進行雜湊。如果沒有提供初始值,預設的建構函式會生成乙個空容器,它有預設個數的格仔。

當我們知道要在容器中儲存多少個元素時,可以在建構函式中指定應該分配的格仔的個數:

std::unordered_mappeople , , }, 10};

這個建構函式有兩個引數:初始化列表和需要分配的格仔數。

也可以用迭代器定義的一段 pair 物件來生成容器。顯然,只要這個範圍內的 pair 物件都是要求的型別,那麼任何物件源都可以接受。例如:

std::vector>folks , , ,,, };

std::unordered_mapneighbors ;

folks 是乙個包含 pair型別元素的 vector 容器,然後用它的元素來填充 neighbors 容器。這裡為 neighbors 分配了 500 個格仔,但也可以省略這個引數,使用預設的格仔個數。可以為前面的兩個建構函式指定定義雜湊函式的函式物件。這個函式物件會分別作為第 1 個建構函式的第 3 個引數,以及第 2 個建構函式的第 4 個引數,所以這時需要為第 2 個建構函式指定格仔個數。接下來會展示如何在接收初始化列表的建構函式中指定這個引數。

假如我們想要用定義在前面章節中的 name 物件作為鍵,那就必須為它定義乙個雜湊函式和乙個恒等運算子,擴充套件後的類的定義如下:

class name

bool operator==(const name& name) const

};在這個示例中,編譯器提供的預設的 operator==() 成員函式能夠滿足我們的要求,但還是想自己定義。成員函式 hash() 用函式物件 hash() 來雜湊 name 物件的成員 first 和 second 所拼接的字串。

unordered_map 容器的雜湊函式只能接受和鍵同型別的單個引數,它會返回乙個 size_t 型別的雜湊值。我們可以定義乙個滿足這些條件的函式物件的型別,這個型別的函式物件會呼叫 name 物件的成員函式 hash():

class hash_name 

};當生成 unordered_map 容器時,可以用 hash_name 物件作為它的比較函式:

std::unordered_mappeople

, 25}, , 46}, , 77}},500,hash name()}

這個容器中的元素是 pair型別物件。它的建構函式的第乙個引數是乙個初始化列表,裡面定義了三個這種型別的物件。注意括號是如何巢狀的。最內層的括號中包含 name 建構函式的引數。它上面的一層包含的是 pair建構函式的引數。

unordered_map 建構函式的第 2 個引數是格仔的個數,我們必須指定它,因為我們想使用第 3 個引數,第 3 個引數是用來雜湊鍵的函式物件。hash_name 型別的函式物件會作為這個容器的第 3 個模板型別引數。這麼做是必要的,因為模板型別引數有乙個不同於我們函式物件的型別的預設值。unordered_map 有以元素段為引數的建構函式,它的前兩個引數是迭代器,第 3 個引數是格仔個數,第 4 個引數是雜湊函式。

當需要指定用來比較兩個鍵物件是否相等的函式物件時,必須指定格仔個數,函式物件會用鍵值來生成雜湊值。如果我們忽略了 name 類的成員函式 operator==(),並且假設定義了乙個定義了函式物件的類型別 name_equal,可以按如下方式在建構函式中指定它:

std::unordered_map, 25}, , 46},, 77}},500,hash_name(), name_equal()};

這裡有乙個額外的模板型別引數和乙個額外的構造函式引數,因為引數有預設值,所以這個模板型別引數是必要的。模板引數列表中用來比較鍵的函式物件同樣會用在以初始化列表為引數的建構函式中。

unordered_map 也有移動和拷貝建構函式。顯然,可以用它們生成容器的副本,副本容器的格仔個數、雜湊函式都和引數容器相同。

初始化 指定初始化

id alloc 物件的誕生過程,主要是從作業系統獲得一塊足夠大的記憶體,以存放該類的全部例項變數,並將其指定為存放記憶體物件的實力變數的位置。alloc方法同時將這塊記憶體全部設定為0。結果是 bool變數初始化為no,所有的int型別變數為0,float變數為0.0,所有的指標為nil.obje...

初始化 1 預設初始化 列表初始化

初始化的基本概念 事實 初始化和賦值是兩個完全不同的操作。初始化,是建立變數時賦予其乙個初始值。賦值,是把物件的當前值擦除,用乙個新值代替。列表初始化 p39 作為c 11新標準的一部分,用花括號 來初始化變數得到了全面應用。出於某些原因,這種初始化的方式叫做列表初始化。現在,無論是初始化物件還是某...

初始化 MyBatis初始化之載入初始化

在mybatis初始化過程中,大致會有以下幾個步驟 1.建立configuration全域性配置物件,會往typealiasregistry別名註冊中心新增mybatis需要用到的相關類,並設定預設的語言驅動類為xmllanguagedriver 3.構建defaultsqlsessionfacto...