要准备要在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成语可以像安全的bool成语一样投射到size_t?或者是其他东西?当每个结构中的公共接口和成员函数更方便时,为每个结构写出一个新的std::hash
特化是愚蠢的。
答案 0 :(得分:4)
实际上还有另一种解决方案:
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>;
现在,您所要做的就是定义一个自由函数hash_value
,它接受T
或T const&
作为参数并返回size_t
。
编辑:将hash
更改为hash_value
,就像在Boost中一样。
答案 1 :(得分:3)
每个结构中的公共接口和成员函数都是远的 更方便。
不会。而不是std::hash
处理哈希,你现在必须使用这个细节打扰 每个类/结构的每个接口。你必须经常处理“我的一些同事删除了Hashable
”。等等不会更好。情况会好很多。
你可以通过SFINAE的部分专业来实现它。