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::hashfor 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