[英]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.