自作クラスをunordered_mapに突っ込むには、std::hash
を特殊化してそのクラスにoperator==
が定義されていないといけません。
operator==
の定義はメンバ変数同士が等価か調べればいいとして、std::hash
を特殊化する時にハッシュ値をどう生成すればいいのか問題になると思います。上手にハッシュ値を生成してやらないと効率の悪いunordered_mapになってしまいます。
boostにはこれに対するhash_combine(size_t & seed, T const& v);
という解決策があるのですが、C++の標準ライブラリには入っていないようです。ググるとこの関数の実装がヒットして次のようになってます。
Reference - 1.55.0
まあこれを自作クラスのハッシュ関数に実装すればいいのです。
ちなみに0x9e3779b9
という数値の理由は2^32 / phi = 0x9e3779b9
みたいです
#include <bits/stdc++.h> using namespace std; struct Hoge { int n; double d; }; bool operator==(const Hoge &lhs, const Hoge &rhs) { return lhs.n == rhs.n && lhs.d == rhs.d; } namespace std { template <> struct hash<Hoge> { size_t operator()(const Hoge &hoge) const { size_t seed = 0; auto n_hash = hash<int>()(hoge.n); auto d_hash = hash<double>()(hoge.d); seed ^= n_hash + 0x9e3779b9 + (seed << 6) + (seed >> 2); seed ^= d_hash + 0x9e3779b9 + (seed << 6) + (seed >> 2); return seed; } }; } int main() { unordered_map<Hoge,int> mp; mp[Hoge{0,1.0}]=1; return 0; }