安全方便的通用散列(用于 STL 无序集和映射)习语?

Safe and convenient generic hashing (for STL unordered set and map) idiom?

本文关键字:无序 映射 习语 STL 用于 方便 安全      更新时间:2023-10-16

要准备一个在unordered_set中使用的结构,需要一个散列函数。 这可以通过重载operator size_t()(ew)或烦人地制作这样的东西来实现:

namespace std
{
template<> struct hash<MyStruct> : public unary_function<MyStruct, size_t>
{
size_t operator()(const MyStruct& mystruct) const
{
return 0; //hash here
}
};
}

有没有办法创建这样的接口:

struct Hashable
{
virtual size_t hash() = 0;
};

并设置std::hash以适用于其任何实现? 我很确定模板不会以这种方式工作,所以这让我陷入困境。 有没有一个安全的size_t成语可以像安全布尔成语一样工作,用于投射到size_t? 还是别的什么? 为每个结构编写新的std::hash专用化是愚蠢的,而每个结构中的公共接口和成员函数会方便得多。

实际上还有另一种解决方案:

template <typename T>
struct Hashable {
size_t operator()(T const& t) { return hash_value(t); }
};
template <typename T, typename E = std::equal<T>, typename A = std::allocator<T>>
using MySet = std::unordered_set<T, Hashable<T>, E, A>;

现在,您所要做的就是定义一个接受TT const&作为参数并返回size_t的自由函数hash_value

编辑:hash更改为hash_value,就像在Boost中一样。

每个结构中的公共接口和一个成员函数会很远 更方便。

不会的。而不是std::hash处理哈希,你现在必须用这个细节来打扰每个类/结构的每个接口。你必须不断地处理"我的某个同事删除了Hashable"。等。这样也好不过了。情况会更糟。

也许,您可以通过SFINAE的部分专业化来实现它。