C++14中unordered_map无法找到已存在键的原因是什么?
问题根因
你定义的std::unordered_map key类型为Example*(指针),而非Example类对象:
- 容器默认的相等比较逻辑是直接比较两个指针的内存地址,不会调用你为
Example类重载的operator== - 你两次
new Example(1)生成的是两个独立对象,内存地址不同,因此find判定为不匹配,自然不会触发你写的相等比较逻辑,也找不到对应条目。
解决方法
方案1:保留指针作为key,自定义相等比较谓词
新增自定义相等比较类,显式指定给unordered_map的第四模板参数:
// 新增相等比较类 class ExampleEqual { public: bool operator()(const Example* a, const Example* b) const { return *a == *b; } }; // 定义map时指定比较类 std::unordered_map<Example*, int, ExampleHash, ExampleEqual> m;
修改后运行代码就会触发operator==的调用,find操作也能正常匹配哈希值相同、值相等的指针对象。
方案2(更推荐):直接使用Example对象作为key
这种方式不需要额外处理指针逻辑,也能避免内存泄漏:
- 修改哈希函数的入参为
const Example&类型 - 把map的key类型改为
Example
修改后核心代码示例:
class ExampleHash { public: size_t operator()(const Example& key) const { std::cout << "Returning hash value " << key.x << "\n"; return key.x; } }; // map定义改为 std::unordered_map<Example, int, ExampleHash> m; // 插入逻辑改为 m[Example(1)] = 1; // 查询逻辑改为 m.find(Example(1))
这种写法默认就会调用Example类重载的operator==,不需要额外自定义比较类,也不会出现指针相关的内存泄漏问题。
额外注意
你当前的示例代码存在内存泄漏问题:所有new出来的Example对象都没有对应的delete操作,实际生产环境使用需要注意内存管理。
内容的提问来源于stack exchange,提问作者Christoph Burschka
相关产品推荐
相关产品推荐

