This post will discuss how to use struct as key to std::unordered_map in C++.

To use struct as a key to std::unordered_map, you need to do two things:

1. Define operator== to compare keys in case of a hash collision

In the previous post, we have seen that the ordered associative containers use a strict weak order to identify their keys. That means two keys x and y are considered to be equal if !(x < y) && !(y < x) is true, i.e., neither x is smaller than y, nor y is smaller than x. So less-than operator is used to detect equality and there is no need to define operator==.

On the other hand, std::unordered_map expects you to define the operator== for your class. This is because the fourth template parameter of std::unordered_map requires a comparison function object that returns true if the keys passed as arguments are equal. It defaults to std::equal_to and implementation of std::equal_to delegates the call to operator==.

2. Create specialized hash function for keys of std::unordered_map function

The unordered associative containers are implemented as a hash table. The third template parameter of std::unordered_map is a hashing function object which defaults to std::hash. Since there is no specialization of std::hash for std::pair in the C++ standard library, you have to define our own specialization for std::hash or use boost::hash from Boost.Functional that works with std::pair.

Download  Run Code

Output:

{Java,Java SE 9}: 2017
{Java,Java SE 8}: 2014
{C++,C++17}: 2017
{C++,C++14}: 2014
{C,C11}: 2011
{C,C99}: 1999

 
Please note that using XOR as a hash combination function can be dangerous. This is because XOR maps identical values to 0, which would end up with far too many collisions in the real world. We should shift/rotate one of the hashes before XORing.

That’s all about using struct as key to std::unordered_map in C++.