In C++, the unordered containers from the standard STL library, such as std::unordered_set and std::unordered_map uses hashing so that finding one item takes $O(1)$ on average. The standard library has also provided convenient built-in hash functions for common types such as std::string so that those common types could be used with the unordered containers seamlessly. Custom types, however, cannot be used with the unordered containers directly because C++ does not know how to hash the custom type.
In this blog post, I would like to discuss how to create hash functions for custom types so that they can be used with the unordered containers in C++.
C++ Custom Hash
Creating a good hash function is research and it is hard. So in this example, we are only going to use the existing built-in hash function to hash custom type that consists of common hashable types.
intmain() { Player const kobe{24, "Kobe Bryant"}; Player const michael{23, "Michael Jordan"}; Player const gilbert{0, "Gilbert Arenas"}; // Tracy and Derrick will be hashed to the same bucket with PlayerHasher. Player const tracy{1, "Tracy McGrady"}; Player const derrick{1, "Derrick Rose"}; Player const chaucey{1, "Chauncey Billups"};
// Custom hash for custom objects requires a hasher and an equal judger. size_tconst min_bucket_count{4}; std::unordered_set<Player, PlayerHasher, PlayerEqual> association( min_bucket_count); association.insert(kobe); association.insert(michael); association.insert(gilbert); association.insert(tracy); association.insert(derrick);
$ g++ hash.cpp -o hash --std=c++14 $ ./hash Number of buckets: 5 Bucket 0 size: 1 Players: 0 Gilbert Arenas Bucket 1 size: 2 Players: 1 Derrick Rose 1 Tracy McGrady Bucket 2 size: 0 Players: Bucket 3 size: 1 Players: 23 Michael Jordan Bucket 4 size: 1 Players: 24 Kobe Bryant Found Tracy McGrady in the association. Found Derrick Rose in the association. Not found Chauncey Billups in the association.