关于C++中的unordered_map和unordered_set不能直接以pair作为键名的问题
在 C++ STL 中,不同于有序的 std::map
和 std::set
是基于红黑树实现的,std::unordered_map
和 std::unordered_set
是基于哈希实现的,在不要求容器内的键有序,仅要求查找效率较高时,哈希实现的后者时更为合适的,哈希表的运用也经常出现在各种算法题中。
但是,我们知道,既然是基于哈希实现的,那么就需要指定哈希函数。对于内置的数据类型如 int
,float
,char
等,STL 库已经帮助我们内置了常用的哈希函数。因此通常,我们在使用这些数据类型组成的 unordered_map 和 unordered_set 可以不再指定哈希函数,直接用默认的。这在 unordered_map 的类模板定义中也可看到:
template < class Key, //容器中存储元素的类型class Hash = hash<Key>, //确定元素存储位置所用的哈希函数class Pred = equal_to<Key>, //判断各个元素是否相等所用的函数class Alloc = allocator<Key> //指定分配器对象的类型> class unordered_set;
在这些参数重,只有第一个参数是没有默认值的。也就是说,在我们创建 int
、char
等内置类型的 unordered_set 时只需要传入存储在容器中的类型即可。
但是,对于没有默认的哈希函数的类型,如自定义的 class 类型,pair 类型等,我们就必须自己指定一个哈希函数。这也是为什么直接构建 pair 类型的 unordered_set 如 unordered_set<pair<int, int>> uset
会出现问题(不会在声明时报错,而是在 insert 等操作时)。
对于这种情况,我们只需要将上面的第二个参数:确定元素存储位置所用的哈希函数,也在声明时传入就行了。关于哈希函数的选择,不同的情景会有所不同。这里笔者给出一个最简单的针对 pair 类型的哈希函数。
struct SimplePairHash {std::size_t operator()(const std::pair<int, int>& p) const {return p.first ^ p.second;}
};
在声明时直接将其传入即可:
std::unordered_set<std::pair<int, int>, SimplePairHash> S;
S.insert(std::make_pair(0, 1));
Ref :
https://stackoverflow.com/questions/21288345/unordered-set-of-pairs-compilation-error
https://blog.csdn.net/pineappleKID/article/details/108341064