关于C++ unordered_map中自定义类型operator()与哈希码的疑问
关于unordered_map中operator()与哈希的关联解答
核心关联:operator()是哈希计算的实现载体
在C++里,unordered_map依赖哈希值快速定位元素,默认用std::hash模板生成键的哈希,但自定义类型没有默认的std::hash实现。这时候需要自己编写哈希逻辑,而重载operator()是实现自定义哈希函数的标准方式:
- 可以定义一个结构体,在其中重载
operator(),让它接收自定义类型对象并返回size_t类型的哈希值,这个结构体可作为unordered_map的第三个模板参数传入。 - 也可以直接特化
std::hash模板,在特化的结构体里重载operator(),这样unordered_map会自动调用这个哈希逻辑。
unordered_map内部对键的处理流程
当unordered_map处理键(插入、查找等操作)时,会按以下步骤执行:
- 调用哈希函数的operator()生成哈希值:用这个值确定元素在哈希表中的桶位置,这是快速定位的核心。
- 用相等判断(通常是operator==)处理冲突:如果两个键的哈希值相同,需要通过相等判断确认它们是否为同一个键,避免哈希冲突导致的错误匹配。
简单示例代码
比如自定义Person类作为键:
#include <unordered_map> #include <string> struct Person { std::string name; int age; }; // 自定义哈希结构体,通过operator()实现哈希计算 struct HashPerson { size_t operator()(const Person& p) const { // 组合name和age的哈希值,实际项目可采用更合理的组合方式 return std::hash<std::string>()(p.name) ^ (std::hash<int>()(p.age) << 1); } }; // 重载相等判断运算符 bool operator==(const Person& a, const Person& b) { return a.name == b.name && a.age == b.age; } // 使用自定义哈希的unordered_map std::unordered_map<Person, std::string, HashPerson> person_info_map;
如果不想传第三个模板参数,也可以特化std::hash:
namespace std { template<> struct hash<Person> { size_t operator()(const Person& p) const { return std::hash<std::string>()(p.name) ^ (std::hash<int>()(p.age) << 1); } }; } // 此时直接使用默认模板参数即可 std::unordered_map<Person, std::string> person_info_map;
内容的提问来源于stack exchange,提问作者Hee Hwang
相关产品推荐
相关产品推荐

