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 with Name and Score members, and operator==() to allow Player objects to be compared for equality. In this case, we consider two Player objects to be equal if they have the same Name.
  • We create a PlayerHash struct that overloads operator()
  • Inside operator(), we combine the hashes of Name and Score 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 the std::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

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Erasing Elements while Iterating
Is it safe to erase elements from a std::unordered_set while iterating over it?
Using a Custom Allocator with std::unordered_set
How can I use a custom allocator with std::unordered_set?
Difference between rehash() and reserve()
What is the difference between rehash() and reserve() in std::unordered_set?
Using std::unordered_set with Smart Pointers
How can I store smart pointers like std::unique_ptr in a std::unordered_set?
Checking if a Key Exists without Inserting
How can I check if a key exists in a std::unordered_set without inserting it if it doesn't?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant