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
Player
struct withName
andScore
members, andoperator==()
to allowPlayer
objects to be compared for equality. In this case, we consider twoPlayer
objects to be equal if they have the sameName
. - We create a
PlayerHash
struct that overloadsoperator()
- Inside
operator()
, we combine the hashes ofName
andScore
using XOR (^
). This ensures that players with the same name but different scores (or vice versa) will have different hashes. - We specify
PlayerHash
as 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