use*_*967 7 c++ hash unordered-set
我std::unordered_set第一次使用a 并且对哈希函数有疑问.据我所知,如果你没有指定哈希函数,它将默认为std::hash<Key>.
我的一个mySet班级有一名成员:
typedef std::unordered_set<MyClass> USetType;
USetType mySet;
Run Code Online (Sandbox Code Playgroud)
当我尝试构建时,我收到以下错误:
错误C2440:'type cast':无法从'const MyClass'转换为'size_t'
size_t如果要使用unordered_set自定义类,是否需要定义转换函数(to )?有没有办法避免编写自己的哈希函数并只使用默认值?
jog*_*pan 12
如果您没有将自己的散列函数指定为模板参数,那么它将默认为std::hash<MyClass>,除非您定义它,否则它不存在.
最好定义你自己的std::hash内部命名空间的专业化std:
namespace std {
template <>
struct hash<MyClass>
{
typedef MyClass argument_type;
typedef std::size_t result_type;
result_type operator()(const MyClass & t) const
{
/* ..calculate hash value for t */
}
};
}
Run Code Online (Sandbox Code Playgroud)
并确保在声明哈希之前包含此代码.这样,您可以简单地声明哈希,std::unordered_set<MyClass>而无需进一步的模板参数.
您没有指定MyClass内部的内容,但典型情况是您的用户定义类型只包含几个简单类型成员,其中存在默认哈希函数.在这种情况下,您可能希望将各个类型的哈希值组合为整个组合的哈希值.Boost库提供了一个hash_combine为此目的而调用的函数.当然,不能保证它在您的特定情况下能够很好地工作(它取决于数据值的分布和碰撞的可能性),但它提供了一个好的且易于使用的起点.
以下是如何使用它的示例,假设MyClass包含两个字符串成员:
#include <unordered_set>
#include <boost/functional/hash.hpp>
struct MyClass
{
std::string _s1;
std::string _s2;
};
namespace std {
template <>
struct hash<MyClass>
{
typedef MyClass argument_type;
typedef std::size_t result_type;
result_type operator()(const MyClass & t) const
{
std::size_t val { 0 };
boost::hash_combine(val,t._s1);
boost::hash_combine(val,t._s2);
return val;
}
};
}
int main()
{
std::unordered_set<MyClass> s;
/* ... */
return 0;
}
Run Code Online (Sandbox Code Playgroud)