This post will discuss how to use std::pair as a key in std::unordered_set in C++.

In the previous post, we have seen that the default value for the second template parameter of std::set is std::less, which will delegate to operator<. Since operator< is defined for pairs, std::set performs a lexicographical comparison on two pair objects to define order. This is the reason the following declaration works in C++:

 
On the other hand, std::unordered_set throws a compilation error when std::pair is used as a key.

This is because unordered containers like std::unordered_set and std::unordered_map uses std::hash for computing hash value for its keys and there is no standard specialization of std::hash for std::pair in the C++ library.

 
To use pair as a key in a std::unordered_set, we can follow any of the following approaches:

1. Using std::hash function

We can define the specialization for std::hash that works with std::pair.

Download  Run Code

Output:

four: 4
one: 1
three: 3
two: 2

 
The above code uses XOR as a hash combination function for simplicity. XOR should be avoided as XOR is symmetric (x ^ y == y ^ x) and maps identical values to zero (x ^ x == y ^ y == 0). This would end up with far too many collisions in the real world. For production code, we should shift/rotate one of the hashes before XORing.

2. Using boost Library

Since there is no specialization of std::hash for std::pair in the standard library, a good alternative is to use the boost::hash from Boost.Functional. We can use it to hash integers, floats, pointers, strings, arrays, pairs, and standard containers.

Download Code

Output:

three: 3
four: 4
one: 1
two: 2

That’s all about using pair as a key in std::unordered_set in C++.