簡體   English   中英

如何通過傳遞命名函數為unordered_set顯式指定自定義哈希函數?

[英]How do I specify a custom hash function explicitly for unordered_set by passing a named function?

基於對此問題的接受答案,可以使用std來為用戶定義的類型提供散列函數。

#include <unordered_set>
#include <stdint.h>


struct FooBar {
    int i; 
};
namespace std {
    template <> struct hash<FooBar>
    {
        size_t operator()(const FooBar & x) const
        {
            return x.i;
        }
    };
}

int main(){
    std::unordered_set<FooBar> foo(0);
}

但是, 文檔似乎暗示自定義散列函數也可以顯式傳遞給構造函數,我想為這個散列函數使用一個命名函數。

但是,我當前的嘗試遭受編譯錯誤。

#include <unordered_set>
#include <stdint.h>

struct FooBar {
    int i; 
};

const size_t hashFooBar(const FooBar& foo) {
    return foo.i;
}

int main(){
    std::unordered_set<FooBar> foo(0, hashFooBar);
}

什么是正確的模板魔術和方法簽名才能使其工作?

你需要提供hasher的類型,在你的情況下是一個函數指針。 而你的FooBar類型必須具有可比性。 或者等效地,您可以以與提供hasher相同的方式提供等式謂詞。

#include <unordered_set>
#include <stdint.h>

struct FooBar {
    int i; 
};

bool operator==(const FooBar& x, const FooBar& y)
{
    return x.i == y.i;
}

size_t hashFooBar(const FooBar& foo) {
    return foo.i;
}

int main(){
    std::unordered_set<FooBar, size_t(*)(const FooBar&)> foo(0, hashFooBar);
}

我還應該注意,提供“仿函數”而不是函數更受歡迎,因為前者可以內聯,而后者可能不會內聯。

#include <unordered_set>
#include <stdint.h>

struct FooBar {
    int i; 
};

bool operator==(const FooBar& x, const FooBar& y)
{
    return x.i == y.i;
}

struct hashFooBar
{
    size_t operator()(const FooBar& foo) const {
        return foo.i;
    }
};

int main(){
    std::unordered_set<FooBar, hashFooBar> foo(0);
}

除了Howard Hinnant的答案 ,它解釋了如何傳遞函數指針和自定義首選(后者嚴格優先),你也可以傳入一個lambda,如下所示:

bool operator==(const FooBar& x, const FooBar& y)
{
    return x.i == y.i;
}

int main() {
    auto hash = [](const FooBar& foo) { return foo.i; };
    std::unordered_set<FooBar, decltype(hash)> set{0, hash};
}

這也可能內聯散列函數,而函數指針版本肯定不會。 您還可以通過打印尺寸來查看:

std::unordered_set<FooBar, decltype(hash)> setLambda{0, hash};
std::unordered_set<FooBar, int(*)(const FooBar&)> setFuncPtr{0, +hash};

std::cout << sizeof(setLambda);   // prints 56
std::cout << sizeof(setFuncPtr);  // prints 64, cause of the
                                  // extra function pointer

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM