一、map
1)最简单的方法就是实现该自定义类型的<操作符,代码如下:
class Foo{public: Foo(int num_) : num(num_) { } bool operator < (const Foo & cmp) const { return num < cmp.num; } int num; };
之后就可以使用Foo作为map的key了:
mapdict;dict[Foo(1)] = 1;
2)定义一个比较操作符,使用它作为map的模板参数,代码如下:
typedef std::pairFoo2;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了:
mapdict2;dict2[Foo2(Foo(1), 100)] = 1;
3)为用户自定义类型特化std::less,代码如下:
namespace std{ template <> struct less: public binary_function { 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>
mapdict2;dict2[Foo2(Foo(1), 100)] = 3;
二、unordered_map
当试图使用自定义类型作为 unordered_map 的键值时,则必须为自定义类型定义 Hash 函数与相等的判断条件。我们先定义自定义类型作键值,代码如下:
struct KEY{ int first; int second; int third; KEY(int f, int s, int t) : first(f), second(s), third(t){}};
1)Hash 函数
必须为 override 了 operator() 的一个类,一般自定义类型可能包含几种内置类型,我们可以分别计算出内置类型的 Hash Value 然后对它们进行 Combine 得到一个哈希值,一般直接采用移位加异或(XOR)便可得到还不错的哈希值(碰撞不会太频繁),如下:
struct HashFunc{ std::size_t operator()(const KEY &key) const { using std::size_t; using std::hash; return ((hash ()(key.first) ^ (hash ()(key.second) << 1)) >> 1) ^ (hash ()(key.third) << 1); }};
2)相等函数
哈希需要处理碰撞,意味着必须得知道两个自定义类型对象是否相等,所以必须得提供比较相等的方法,可以 重载operator ==,可以用 std::equal,也可以实现一个 重写 operator () 的类,这里我们采用后者,代码如下:
struct EqualKey{ bool operator () (const KEY &lhs, const KEY &rhs) const { return lhs.first == rhs.first && lhs.second == rhs.second && lhs.third == rhs.third; }};
下面为一个具体应用的例子:
int main(){ unordered_maphashmap = { { { 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.html
http://www.ithao123.cn/content-10629313.html