Skip to content

Instantly share code, notes, and snippets.

@beyondwdq
Last active December 21, 2020 21:58
Show Gist options
  • Save beyondwdq/7245893 to your computer and use it in GitHub Desktop.
Save beyondwdq/7245893 to your computer and use it in GitHub Desktop.
std::unordered_map with custom key type
g++ -std=c++11 custom_hash.cc -o custom_hash
#include <iostream>
#include <unordered_map>
#include <boost/functional/hash.hpp>
struct KeyData
{
int id;
int age;
// equality
bool operator == (const KeyData &other) const {
return (id == other.id) && (age == other.age);
}
};
struct KeyDataHasher
{
std::size_t operator () (const KeyData &key) const
{
// The following line is a stright forward implementation. But it can be
// hard to design a good hash function if KeyData is complex.
//return (key.id << 32 | key.age); // suppose size_t is 64-bit and int is 32-bit
// A commonly used way is to use boost
std::size_t seed = 0;
boost::hash_combine(seed, boost::hash_value(key.id));
boost::hash_combine(seed, boost::hash_value(key.age));
return seed;
}
};
using namespace std;
int main(int argc, const char *argv[])
{
KeyData k1{0, 30}, k2{1, 1}, k3{2, 0};
// Print the hash results
KeyDataHasher hasher;
cout << hasher(k1) << endl
<< hasher(k2) << endl
<< hasher(k3) << endl;
// Construct an unordered_map using KeyData, which maps
// KeyData -> int, using KeyDataHasher as hash function
typedef std::unordered_map<KeyData, int, KeyDataHasher> KeyDataHashMap;
KeyDataHashMap mapping{ {k1, 1}, {k2, 2}, {k2, 3} };
for (auto &kv : mapping) {
cout << "id:" << kv.first.id
<< " age:" << kv.first.age
<< " value:" << kv.second << endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment