自定义哈希的shared_ptr作为unordered_map键无法正常查找问题
问题分析与解决
你遇到的问题核心是:仅自定义哈希函数不足以让unordered_map按字符串内容判断键是否相等。unordered_map的键匹配需要两个条件:哈希值相同,且通过相等谓词判断为相等。你只替换了哈希函数,但默认的相等谓词仍然使用shared_ptr的operator==——也就是比较指针的内存地址,而非指向的字符串内容。哪怕p1和p2指向的字符串内容一致,它们是不同的指针实例,默认相等判断会认为是不同的键,这就是查找失败的原因。
要解决这个问题,必须同时为unordered_map指定自定义的相等谓词,让它基于字符串内容判断两个shared_ptr是否相等。
修正后的代码
#include <iostream> #include <memory> #include <unordered_map> using namespace std; int main() { // 自定义哈希函数:基于字符串内容计算哈希值 auto hashFn = [](const shared_ptr<string>& p) -> size_t { return hash<string>()(*p); }; // 自定义相等谓词:比较两个shared_ptr指向的字符串内容 auto equalFn = [](const shared_ptr<string>& a, const shared_ptr<string>& b) -> bool { return *a == *b; }; // 初始化unordered_map时,同时传入哈希函数和相等谓词 auto map = unordered_map<shared_ptr<string>, int, decltype(hashFn), decltype(equalFn)>(0, hashFn, equalFn); auto p1 = shared_ptr<string>(new string("abc")); auto p2 = shared_ptr<string>(new string("abc")); auto [_it, flag] = map.emplace(p1, 0); cout << flag << endl; // 输出1,表示插入成功 int c = map.count(p2); cout << c << endl; // 现在输出1,查找成功 return 0; }
关键说明
- 添加了
equalFnlambda表达式,专门比较两个shared_ptr指向的字符串内容是否一致; - 在
unordered_map的模板参数中,新增了相等谓词的类型decltype(equalFn); - 初始化容器时,构造函数同时传入哈希函数和相等谓词对象。
这样unordered_map就会同时依据字符串内容计算哈希、判断相等,符合你预期的键匹配逻辑。
内容的提问来源于stack exchange,提问作者small-turtle
相关产品推荐
相关产品推荐

