unordered_map定义(C++11) 参考博客
1 2 3 4 5 6 7 template < class Key , class T , class Hash = std : :hash<Key>, class KeyEqual = std : :equal_to<Key>, class Allocator = std : :allocator< std ::pair<const Key, T> > > class unordered_map ;
Key代表键值(key),T是根据哈希函数得到的值(value),Hash是哈希函数的函数对象,KeyEqual是等比函数的函数对象,通过"=="
来判断两个key是否相等。 想实现自定义的键类型,必须实现hash函数和等比函数。
实现
法一:利用std::function中的默认hash函数std::hash
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 #include <functional> #include <unordered_map> class mypair { public : char first; char second; mypair(char a, char b) { if ( a < b) { first = a; second = b; } else { first = b; second = a; } } bool operator ==(const mypair& rhs) { return rhs.first == this ->first && rhs.second == this ->second; } }; static size_t mypair_hash (const mypair& tmp) { return hash<char >()(tmp.first) ^ hash<char >()(tmp.second); } int main () { unordered_map<mypair, int, decltype(&mypair_hash)> memo(20/*, mypair_hash*/); //在这里decltype后面必须要使用引用 }
Note:
1) decltype(exp)推导的内容如果是一个左值,那么 decltype(exp) 的类型就是 exp 的引用。在这里mypair_hash是一个函数,如果是自动推导得到的是函数的返回值,不是引用类型,运行时编译器会报错,在hashtable_policy.h中:field 'std::__detail::_Hashtable_ebo_helper<1, long long unsigned int(const mypair&), false>::_M_tp' invalidly declared function type
2) 参考的博客中说memo初始化时必须传入mypair_hash构造函数,但是我尝试不传入发现也是可以编译通过和运行的。
法二:重载operator()类,打包哈希函数变成函数对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class mypair { public : char first; char second; mypair(const char & a, const char & b) { first = a; second = b; } bool operator ==(const mypair& rhs) const { return rhs.first == first && rhs.second == second; } }; struct hashname { size_t operator () (const mypair& tmp) const { return (hash<char >()(tmp.first)) ^ (hash<char >()(tmp.second)); } }; int main () { unordered_map<mypair, int, hashname> memo(20); }
可以直接运行通过,没有什么坑。