Writing Custom Hash Functions

How can I write a custom hash function for my own data type?

To write a custom hash function for your own data type, you need to specialize the std::hash template for your type. Here's a step-by-step guide:

Step 1: Create your custom data type, for example, a Person struct:

#include <string>

struct Person {
  std::string name;
  int age;
};

Step 2: Specialize the std::hash template for your data type:

#include <utility>
#include <string>

namespace std {
template <>
struct hash<Person> {
  size_t operator()(const Person& person) const {
    // Combine the hash values of name and age
    size_t nameHash =
      std::hash<std::string>{}(person.name);
    size_t ageHash =
      std::hash<int>{}(person.age);
    return nameHash ^ (ageHash << 1);  
  }
};
}

In the operator() function, you define how to calculate the hash value for your data type. In this example, we combine the hash values of the name and age members using the XOR operator (^) and left shift (<<).

Step 3: Ensure that your data type has a proper equality comparison operator (operator==):

bool operator==(const Person& lhs,
  const Person& rhs) {
  return lhs.name == rhs.name
    && lhs.age == rhs.age;
}

This is necessary because hash tables use equality comparison to resolve collisions.

Now you can use your custom data type with hash-based containers like std::unordered_set or std::unordered_map:

#include <utility>
#include <string>
#include <iostream>
#include <unordered_set>

struct Person {/*...*/}
bool operator==(Person, Person) {/*...*/}
namespace std {/*...*/} int main() { std::unordered_set<Person> people; people.insert({"John", 30}); people.insert({"Alice", 25}); for (const auto& person : people) { std::cout << person.name << " - " << person.age << '\n'; } }
John - 30
Alice - 25

Remember, a good hash function should distribute the hash values uniformly across the range of possible values to minimize collisions and maintain the efficiency of hash-based containers.

Hashing and std::hash

This lesson provides an in-depth look at hashing in C++, including std::hash, collision strategies, and usage in hash-based containers.

Questions & Answers

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

When to Use Hash Tables
In what scenarios are hash tables a good choice compared to other data structures?
Handling Hash Collisions
What happens when there is a collision in a hash table, and how is it handled?
std::unordered_map vs std::map
What are the differences between std::unordered_map and std::map in C++?
Hash Table Load Factor
What is the load factor of a hash table, and how does it affect performance?
Hash Table vs Binary Search Tree
When should I use a hash table (std::unordered_map) versus a binary search tree (std::map)?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant