为何std::unordered_map的operator==未使用自定义KeyEqual?
问题解答
1. 为什么std::unordered_map的operator==不使用其KeyEqual模板参数?
C++标准明确规定:std::unordered_map的operator==判断两个容器相等的逻辑是——两者键值对数量相同,且每个键值对都能在对方容器中找到完全匹配的对应项。这里的键相等判断用的是键类型自身的operator==,而非容器的KeyEqual模板参数。
KeyEqual的作用是服务于容器内部的哈希组织逻辑:当哈希值冲突时,它用来判断两个键是否属于等价键(即是否应该被视为同一个键,避免重复插入),和容器整体的相等性比较是两个独立的逻辑。
2. 代码输出不符合预期的原因
你代码中map11 == map22输出0的核心原因是:
std::unordered_map的operator==比较键时,用的是键类型(Base*)默认的operator==——也就是直接比较指针的内存地址,而非你特化的std::equal_to<Base*>。map11的键是&b1、&b2,map22的键是&bb1、&bb2,这些是不同对象的地址,所以&b1 == &bb1结果为false,导致对应的键值对无法匹配,最终两个容器被判定为不相等。
而map11 == map33输出1,是因为两者的键是完全相同的指针地址,自然能匹配成功。
如果想让指针作为键的unordered_map在operator==时按自定义规则比较键,你可以:
- 改用封装类替代原生指针,重载其
operator==实现自定义比较逻辑; - 或者不依赖
operator==,自己实现容器相等性检查——遍历容器时用KeyEqual判断键的等价性,同时比较值是否相等。
修改示例
比如封装一个指针类来替代原生指针:
struct BasePtr { Base* ptr; BasePtr(Base* p) : ptr(p) {} bool operator==(const BasePtr& other) const { return *ptr == *other.ptr; } }; // 特化hash适配 template <> struct std::hash<BasePtr> { size_t operator()(const BasePtr& bp) const { return bp.ptr->hash(); } }; // 使用方式 std::unordered_map<BasePtr, int> map11{{&b1, 1}, {&b2, 2}}; std::unordered_map<BasePtr, int> map22{{&bb1, 1}, {&bb2, 2}}; cout << (map11 == map22) << endl; // 此时输出1
内容的提问来源于stack exchange,提问作者Trams
相关产品推荐
相关产品推荐

