How do I make my custom type work with std::unordered_map
?
I have a custom type that I want to use as a key in std::unordered_map
. What do I need to do to make it work?
To use a custom type as a key in std::unordered_map
, you need to specialize the std::hash
template for your type. The std::hash
template is used by std::unordered_map
to compute the hash value of the keys.
Here's how you can specialize std::hash
for your custom type:
- Create a specialization of
std::hash
for your type. - Implement the
operator()
function that takes an object of your type and returns a hash value.
Here's an example:
#include <string>
#include <unordered_map>
struct MyType {
int id;
std::string name;
// ... other members ...
};
namespace std {
template <>
struct hash<MyType> {
size_t operator()(const MyType& obj) const {
size_t idHash = std::hash<int>()(obj.id);
size_t nameHash = std::hash<
std::string>()(obj.name);
// Combine the hash values
return idHash ^ (nameHash << 1);
}
};
}
In this example, MyType
is a custom type with an id
and a name
member. The specialization of std::hash<MyType>
is defined in the std
namespace.
The operator()
function takes an object of MyType
and computes its hash value. In this case, we compute the hash values of the id
and name
members separately using std::hash<int>
and std::hash<std::string>
, respectively. Then, we combine the hash values using the XOR (^
) operator and a bit shift (<<
) to create the final hash value.
Once you have specialized std::hash
for your type, you can use MyType
as a key in std::unordered_map
:
std::unordered_map<MyType, int> myMap;
MyType obj1{1, "Object 1"};
MyType obj2{2, "Object 2"};
myMap[obj1] = 10;
myMap[obj2] = 20;
The std::unordered_map
will use the specialized std::hash<MyType>
to compute the hash values of the keys and efficiently store and retrieve the elements.
Note: Make sure that your hash function provides a good distribution of hash values to minimize collisions and ensure efficient performance of the std::unordered_map
.
Template Specialization
A practical guide to template specialization in C++ covering full and partial specialization, and the scenarios where they're useful