class Foo { public: Foo(int num_) : num(num_) { } bool operator < (const Foo & cmp) const { return num < cmp.num; } int num; };
以後就能夠使用Foo做爲map的key了:html
map<Foo, int> dict; dict[Foo(1)] = 1;
typedef std::pair<Foo, int> Foo2; class Foo2Comparator { public: bool operator()(const Foo2& key1, const Foo2& key2) const { if (key1.first < key2.first) { return true; } else if (key2.first < key1.first) { return false; } else { return key1.second < key2.second; } } };
這時候能夠使用Foo2做爲map的key了:less
map<Foo2, int, Foo2Comparator> dict2; dict2[Foo2(Foo(1), 100)] = 1;
namespace std { template <> struct less<Foo2> : public binary_function <Foo2, Foo2, bool> { bool operator()(const Foo2& key1, const Foo2& key2) const { if (key1.first < key2.first) { return true; } else if (key2.first < key1.first) { return false; } else { return key1.second < key2.second; } } }; }
使用這種方法,聲明map時無需指定比較函數對象,由於默認的比較對象就是std::less<T>ide
map<Foo2, int> dict2; dict2[Foo2(Foo(1), 100)] = 3;
當試圖使用自定義類型做爲 unordered_map 的鍵值時,則必須爲自定義類型定義 Hash 函數與相等的判斷條件。咱們先定義自定義類型做鍵值,代碼以下:函數
struct KEY { int first; int second; int third; KEY(int f, int s, int t) : first(f), second(s), third(t){} };
必須爲 override 了 operator() 的一個類,通常自定義類型可能包含幾種內置類型,咱們能夠分別計算出內置類型的 Hash Value 而後對它們進行 Combine 獲得一個哈希值,通常直接採用移位加異或(XOR)即可獲得還不錯的哈希值(碰撞不會太頻繁),以下:spa
struct HashFunc { std::size_t operator()(const KEY &key) const { using std::size_t; using std::hash; return ((hash<int>()(key.first) ^ (hash<int>()(key.second) << 1)) >> 1) ^ (hash<int>()(key.third) << 1); } };
哈希須要處理碰撞,意味着必須得知道兩個自定義類型對象是否相等,因此必須得提供比較相等的方法,能夠 重載operator ==,能夠用 std::equal,也能夠實現一個 重寫 operator () 的類,這裏咱們採用後者,代碼以下:code
struct EqualKey { bool operator () (const KEY &lhs, const KEY &rhs) const { return lhs.first == rhs.first && lhs.second == rhs.second && lhs.third == rhs.third; } };
下面爲一個具體應用的例子:htm
int main() { unordered_map<KEY, string, HashFunc, EqualKey> hashmap = { { { 01, 02, 03 }, "one" }, { { 11, 12, 13 }, "two" }, { { 21, 22, 23 }, "three" }, }; KEY key(11, 12, 13); auto it = hashmap.find(key); if (it != hashmap.end()) { cout << it->second << endl; } return 0; }
參考資料:對象
http://blog.sina.com.cn/s/blog_48d4cf2d0100mx4t.htmlblog
http://www.ithao123.cn/content-10629313.htmlthree