如果您不指定自己的哈希函子作为模板参数,它将默认为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 */
}
};
}
并确保在声明哈希之前包含此代码。通过这种方式,您可以简单地声明哈希,std::unordered_set<MyClass>
而无需进一步的模板参数。
You didn't specify what MyClass
looks like inside, but a typical situation is that your user-defined type simply consists of several simple-type members, for which a default hash function exists. In this case, you will probably want to combine the hash values for the individual types to a hash value for the entire combination. The Boost library provides a function called hash_combine
for this purpose. Of course, there is no guarantee that it will work well in your particular case (it depends on the distribution of data values and the likelihood of collisions), but it provides a good and easy-to-use starting point.
Here is an example of how to use it, assuming MyClass
consists of two string members:
#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;
}