If you do not specify your own hash functor as an argument to the template, the default is std::hash<MyClass> , which does not exist if you do not define it.
Better define your own specialization std::hash inside the std :
namespace std { template <> struct hash<MyClass> { typedef MyClass argument_type; typedef std::size_t result_type; result_type operator()(const MyClass & t) const { } }; }
And make sure you include this code before declaring your hash. That way, you can declare the hash simply as std::unordered_set<MyClass> without requiring further template arguments.
You did not specify what MyClass looks like inside, but the typical situation is that your custom type simply consists of several members of a simple type, for which there is a default hash function. In this case, you probably want to combine the hash values ββfor the individual types with the hash value for the whole combination. For this purpose, the Boost library provides a function called hash_combine . 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 probability of collisions), but this provides a good and convenient starting point.
Here's an example of how to use it, assuming MyClass is a two-line member:
#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; }
jogojapan
source share