std::unordered_map自定义比较器未触发问题求助
问题:std::unordered_map的自定义比较器未触发
我为std::string实现了自定义比较器:
struct MyComparator { bool operator()(const std::string& lhs, const std::string& rhs) const { return some_odd_strings_comparison_here; // 自定义字符串比较逻辑 } };
并将其应用到std::unordered_map中:
std::unordered_map<std::string, T, std::hash<std::string>, MyComparator> some_odd_map = {{...}, {...}, ...};
最终想通过find方法查找元素:
auto el = some_odd_map.find(smthng); if (el != some_odd_map.end()) { // 找到目标元素 }
但实际运行时,自定义比较器从未被触发。
原因分析
std::unordered_map的底层逻辑是先通过哈希函数计算键的哈希值,将键分配到对应的哈希桶中;只有当两个键的哈希值完全相同时,才会调用比较器来判断它们是否逻辑相等。
你当前使用的是默认的std::hash<std::string>,它会基于字符串的原始字节生成哈希值。如果你的自定义比较器认为相等的两个字符串(例如大小写不同的字符串),它们的默认哈希值却不相同,那么unordered_map会将它们放入不同的哈希桶,自然不会触发比较器的调用。
解决方法
必须同时自定义哈希函数和比较器,保证一个核心规则:
如果
MyComparator()(a, b) == true(即a和b逻辑相等),那么自定义哈希函数计算出的hash(a)必须等于hash(b)
以下是一个完整示例(以忽略大小写的字符串比较为例):
// 自定义哈希函数:忽略大小写计算字符串哈希值 struct MyHash { size_t operator()(const std::string& s) const { size_t hash_val = 0; for (char c : s) { // 转为小写后计算哈希,保证逻辑相等的字符串哈希一致 hash_val = hash_val * 31 + std::tolower(static_cast<unsigned char>(c)); } return hash_val; } }; // 自定义比较器:忽略大小写判断字符串是否相等 struct MyComparator { bool operator()(const std::string& lhs, const std::string& rhs) const { if (lhs.size() != rhs.size()) return false; for (size_t i = 0; i < lhs.size(); ++i) { if (std::tolower(static_cast<unsigned char>(lhs[i])) != std::tolower(static_cast<unsigned char>(rhs[i]))) { return false; } } return true; } }; // 使用自定义哈希和比较器的unordered_map std::unordered_map<std::string, int, MyHash, MyComparator> my_map = { {"Apple", 1}, {"Banana", 2} }; // 测试查找:输入小写的"apple"也能找到对应的元素 auto it = my_map.find("apple"); if (it != my_map.end()) { // 此时比较器会被触发,成功找到键为"Apple"的元素 }
内容的提问来源于stack exchange,提问作者jevgenij
相关产品推荐
相关产品推荐

