C++ 中的 std::hash 模板類

Jinku Hu 2023年1月30日 2021年10月2日
  1. 使用 std::hashstd::string 物件生成雜湊
  2. 使用 std::hashstd::bitset 物件生成雜湊
  3. 使用 std::hashstd::vector<bool> 物件生成雜湊
C++ 中的 std::hash 模板類

本文將介紹 C++ 中來自 STL 的 std::hash 模板類。

使用 std::hashstd::string 物件生成雜湊

std::hash 模板類在 STL <functional> 標頭下提供。它建立一個雜湊函式物件。std::hash 滿足 DefaultConstructible 型別的要求,它只需要提供模板引數。

C++ 標準庫中提供了這個模板類的多個預設特化,完整列表可以在這裡看到。一旦使用給定的模板引數建立了雜湊函式物件,就可以使用它來生成特定的雜湊值,使用 operator() 接受單個引數並返回 size_t 值。

在下一個示例中,我們使用 string 特化併為任意字串生成一些雜湊值。

#include <iostream>
#include <iomanip>
#include <functional>

using std::cout; using std::endl;
using std::setw; using std::string;

int main() {
    string str1("arbitrary string");
    std::vector<string> vec2 = {"true", "false", "false", "true", "false", "true"};

    std::hash<string> str_hash;

    cout << "hash(str1) - " << str_hash(str1) << endl;

    cout << "hash(vec2 elements) - ";
    for (const auto &item : vec2) {
        cout << str_hash(item) << ", ";
    }
    cout << endl;


    return EXIT_SUCCESS;
}

輸出:

hash(str1) - 3484993726433737991
hash(vec2 elements) - 1325321672193711394, 3658472883277130625, 3658472883277130625, 1325321672193711394, 3658472883277130625, 1325321672193711394,

使用 std::hashstd::bitset 物件生成雜湊

STL 中提供的 std::hash 的另一個專門化是用於 std::bitset 引數。請記住,std::bitset 是將固定數量的位表示為序列的類,它提供了多個成員函式以方便位操作。

通常,std::hash 特化使用的雜湊函式是依賴於實現的,不應將這些物件用作雜湊問題的通用解決方案。此外,這些雜湊函式只需要在程式的單次執行中為相同的輸入產生相同的輸出。

#include <iostream>
#include <iomanip>
#include <functional>
#include <bitset>

using std::cout; using std::endl;
using std::setw; using std::string;

int main() {
    std::bitset<8> b1("00111001");

    std::hash<std::bitset<8>> bitset_hash;

    cout << "hash(bitset<8>) - " << bitset_hash(b1) << endl;

    return EXIT_SUCCESS;
}

輸出:

hash(bitset<8>) - 6623666755989985924

使用 std::hashstd::vector<bool> 物件生成雜湊

我們還可以對布林值的 vector 使用 std::hash 特化,如下面的程式碼片段所示。請注意,std::hash 也可以為使用者定義的類進行專業化處理,一些額外的專業化處理可以通過 Boost 庫來實現(詳細內容見這裡

#include <iostream>
#include <iomanip>
#include <functional>

using std::cout; using std::endl;
using std::setw; using std::string;

int main() {
    std::vector<bool> vec1 = {true, false, false, true, false, true};

    std::hash<std::vector<bool> > vec_str_hash;

    cout << "hash(vector<bool>) - " << vec_str_hash(vec1) << endl;

    return EXIT_SUCCESS;
}

輸出:

hash(vector<bool>) - 12868445110721718657
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn