Hash function definition in TR1 unordered_map inside structure

According to this , you can define an equality function in TRN unordered_map as follows:

#include <tr1/unordered_map> using namespace std; using namespace std::tr1; struct foo{ ... bool operator==(const foo& b) const{ return ..; } }; unordered_map<foo,int> map; 

Is it also possible to define a hash function?

+4
source share
2 answers

If you want to change the default hashing (or, most often, provide hashing for a type that is not currently supported), you provide the specialization std::tr1::hash<T> for your key type:

 namespace std { namespace tr1 { template<> struct hash<typename my_key_type> { std::size_t operator()(my_key_type const &key) { return whatever; } }; } } 

Note that specializing an existing template for a custom type is one of the rare cases where you are definitely allowed to write code in namespace std .

+12
source

The signature of the unordered_map class is this:

 template<class Key, class Ty, class Hash = std::hash<Key>, class Pred = std::equal_to<Key>, class Alloc = std::allocator<std::pair<const Key, Ty> > > class unordered_map; 

Your example works because by default Pred, std :: equal_to <> by default checks equality using the == operator. The compiler finds your function foo :: operator == member and uses this.

std :: hash does not have a specialization that will call a member function in your class, so you cannot just add a member to foo with a custom hash. You will need to specialize in std :: hash. If you want to call a member function in foo, go ahead. You will get something like this:

 struct foo { size_t hash() const { // hashing method here, return a size_t } }; namespace std { // Specialise std::hash for foo. template<> class hash< foo > : public unary_function< foo, size_t > { public: size_t operator()( const foo& f ) { return f.hash(); } }; } 
+1
source

Source: https://habr.com/ru/post/1345241/


All Articles