Implementing a Custom Hash Function
How can I implement a custom hash function for my user-defined type to use with std::unordered_set?
To implement a custom hash function for your user-defined type, you need to create a struct that overloads the operator(). Here's an example:
#include <unordered_set>
#include <string>
struct Player {
std::string Name;
int Score;
};
struct PlayerHash {
size_t operator()(const Player& P) const {
return std::hash<std::string>{}(P.Name)
^ std::hash<int>{}(P.Score);
}
};For our type to be compatible with hash-based containers such as std::unordered_set, it additionally needs to implement the == operator:
#include <string>
#include <unordered_set>
struct Player {
std::string Name;
int Score;
bool operator==(const Player& Other) const {
return Name == Other.Name;
}
};
struct PlayerHash {
size_t operator()(const Player& P) const {
return std::hash<std::string>{}(P.Name)
^ std::hash<int>{}(P.Score);
}
};
int main() {
std::unordered_set<Player, PlayerHash> Players;
Players.emplace("Alice", 100);
Players.emplace("Bob", 200);
}In this example:
- We define a
Playerstruct withNameandScoremembers, andoperator==()to allowPlayerobjects to be compared for equality. In this case, we consider twoPlayerobjects to be equal if they have the sameName. - We create a
PlayerHashstruct that overloadsoperator() - Inside
operator(), we combine the hashes ofNameandScoreusing XOR (^). This ensures that players with the same name but different scores (or vice versa) will have different hashes. - We specify
PlayerHashas the second template argument when creating thestd::unordered_set
By providing a custom hash function, we enable std::unordered_set to efficiently store and retrieve Player objects.
Hash Sets using std::unordered_set
This lesson provides a thorough understanding of std::unordered_set, from basic initialization to handling custom types and collisions