3 回答
TA贡献1802条经验 获得超10个赞
明确允许并鼓励您向名称空间* 添加特殊化std。添加哈希函数的正确方法(基本上是唯一方法)是:
namespace std {
template <> struct hash<Foo>
{
size_t operator()(const Foo & x) const
{
/* your code here, e.g. "return hash<int>()(x.value);" */
}
};
}
(您可能考虑支持其他受欢迎的专业有std::less,std::equal_to和std::swap。)
*)我想,只要其中一种涉及类型是用户定义的即可。
TA贡献1719条经验 获得超6个赞
我的赌注将放在unordered_map / unorder_set / ...类的Hash模板参数上:
#include <unordered_set>
#include <functional>
struct X
{
int x, y;
std::size_t gethash() const { return (x*39)^y; }
};
typedef std::unordered_set<X, std::size_t(*)(const X&)> Xunset;
typedef std::unordered_set<X, std::function<std::size_t(const X&)> > Xunset2;
int main()
{
auto hashX = [](const X&x) { return x.gethash(); };
Xunset my_set (0, hashX);
Xunset2 my_set2(0, hashX); // if you prefer a more flexible set typedef
}
当然
hashX可能也是一个全局静态函数
在第二种情况下,您可以通过
老式仿函数对象(struct Xhasher { size_t operator(const X&) const; };)
std::hash<X>()
任何满足签名的绑定表达式-
TA贡献1775条经验 获得超11个赞
涵盖了1)和3)。
2)即使g ++和VC10声明std::hash<T>::operator()具有不同的签名,两种库实现也符合标准。
该标准未指定的成员std::hash<T>。它只是说每个这样的专业化必须满足的第二个模板参数等的相同“散列”要求std::unordered_set。即:
哈希类型H是一个函数对象,至少具有一个参数类型Key。
H 是可复制构造的。
H 是可破坏的。
如果h是类型H或的表达式const H,并且k是可以转换为(可能const)的类型的表达式Key,则h(k)是类型为的有效表达式size_t。
如果h是类型H或的表达式const H,并且u是类型的左值Key,则h(u)是一个有效的表达式,其类型size_t不会修改u。
- 3 回答
- 0 关注
- 796 浏览
添加回答
举报