Customizing TR1 unordered_map Hashing and Equality Functions

A common problem people run into when using the C++ std::tr1::unordered_map or std::tr1::unordered_set is when they want to use a custom or aggregate type as the key in the hash table, and aren’t sure how to do it.

There isn’t really any official documentation about this; you can find some forum and StackOverflow discussions which may help; but I’ll run through a detailed example here too. Let’s start by taking a look at how the unordered_map class is defined:

The function represented in class Hash produces a hash value given a reference to type Key. This is the value that the map will use to locate the appropriate bucket to insert the corresponding value. The function represented by Pred is a predicate; it returns true if the values (as opposed to hash values) of Key types are equal. If the Key type is a class with operator== () defined, then defining a separate Pred function won’t be an issue.

Changing the Hash and Pred types is easy, but non-obvious. The most common reasons for this are either using a custom type as the key for the hash table, as I mentioned above, or for using a custom hash function to achieve better performance from the container.

The same logic applies to the std::tr1::unordered_set, with the exception that its template list doesn’t include a class T value type. Also note that you can grab the any map’s default hash function and equality predicate at any time from the object:

Many thanks! I’ve been trying to figure this out for the last few hours, trawling through SO and other forums. This is the only actually complete, working example that I’ve been able to find, and it was just what I needed!

The hash and equality functions are implementation-dependent – it all depends on how you want to do it. The equality test is straightforward: just test equality of each of the fields in the AggregateKey. For the hash, throw the AggregateKey struct into a hashing function like murmur hash or the like.

the equality bit is pretty simple, but i still don’t quite get how i ought to go about the custom hashing function. i realize that this will be implementation dependent to a certain extent, but any working example with a struct or class based key would probably provide sufficient insight to generalize the process. are there any actual examples of doing this out there? i’ve been unable to find any.

for example, how would i go about “throwing the aggregatekey struct into a hashing function like murmur”? i looked up the murmur project on googlecode, but there appear to be no examples of how to use it. clearly it is popular and does an excellent job, but for a noob like me it might as well be greek (and i dont speak greek).