首页 > 后端开发 > C++ > 正文

c++中如何定义一个哈希函数用于自定义类型的unordered_map_c++自定义哈希函数编写方法

裘德小鎮的故事
发布: 2025-10-15 10:24:02
原创
535人浏览过
在C++中使用std::unordered_map存储自定义类型需提供哈希函数,1. 可特化std::hash模板并重载operator==;2. 或传递自定义哈希函数对象;3. 多字段组合推荐用质数混合避免冲突;4. 注意哈希一致性与相等比较的实现。

c++中如何定义一个哈希函数用于自定义类型的unordered_map_c++自定义哈希函数编写方法

在C++中使用std::unordered_map存储自定义类型时,如果该类型没有默认的哈希支持,就需要手动提供一个哈希函数。可以通过特化std::hash或传递自定义哈希函数对象来实现。

1. 特化 std::hash 模板

这是最常见的方式,适用于作为键的自定义结构体或类。

示例:定义一个表示二维点的结构体,并为其特化std::hash

#include <unordered_map><br>#include <iostream><br><br>struct Point {<br>    int x, y;<br>    Point(int x, int y) : x(x), y(y) {}<br><br>    // 重载 == 运算符(unordered_map 需要)<br>    bool operator==(const Point& other) const {<br>        return x == other.x && y == other.y;<br>    }<br>};<br><br>// 自定义 hash 特化<br>namespace std {<br>    template<><br>    struct hash<Point> {<br>        size_t operator()(const Point& p) const {<br>            // 使用哈希组合技巧<br>            size_t h1 = hash<int>{}(p.x);<br>            size_t h2 = hash<int>{}(p.y);<br>            // 简单异或 + 位移避免对称性问题<br>            return h1 ^ (h2 << 1);<br>        }<br>    };<br>}<br><br>int main() {<br>    unordered_map<Point, string> pointMap;<br>    pointMap[Point(1, 2)] = "origin";<br>    pointMap[Point(3, 4)] = "target";<br><br>    for (const auto& [pt, label] : pointMap) {<br>        cout << "(" << pt.x << "," << pt.y << "): " << label << endl;<br>    }<br>    return 0;<br>}
登录后复制

2. 使用独立的函数对象(Functor)

如果不希望或不能在std::命名空间中添加特化(比如涉及第三方类型),可以传入自定义哈希类作为模板参数。

通义万相
通义万相

通义万相,一个不断进化的AI艺术创作大模型

通义万相 596
查看详情 通义万相

struct PointHash {<br>    size_t operator()(const Point& p) const {<br>        size_t h1 = hash<int>{}(p.x);<br>        size_t h2 = hash<int>{}(p.y);<br>        return h1 ^ (h2 << 1);<br>    }<br>};<br><br>// 使用方式:<br>unordered_map<Point, string, PointHash> pointMap;<br>
登录后复制

3. 哈希组合建议

多个字段组合时,简单异或可能造成冲突(如(1,2)(2,1)哈希相同)。推荐使用更稳健的方法:

立即学习C++免费学习笔记(深入)”;

  • 使用质数乘法混合:h1 + 0x9e3779b9 + (h2 << 6) + (h2 >> 2)
  • 调用std::hash_combine(虽然标准未直接提供,但可模仿 Boost 实现)
  • 利用 C++ 标准库中的散列组合技巧
一个更安全的组合方式:

size_t operator()(const Point& p) const {<br>    size_t seed = 0;<br>    seed ^= hash<int>{}(p.x) + 0x9e3779b9 + (seed << 6) + (seed >> 2);<br>    seed ^= hash<int>{}(p.y) + 0x9e3779b9 + (seed << 6) + (seed >> 2);<br>    return seed;<br>}
登录后复制

4. 注意事项

  • 必须同时重载operator==,因为unordered_map需要判断键是否相等
  • 哈希函数应尽量均匀分布,减少碰撞
  • 特化std::hash应在std命名空间内,且只能针对用户定义类型
  • 确保哈希值计算是确定性的(相同输入始终产生相同输出)
基本上就这些。只要提供好哈希函数和相等比较,自定义类型就能顺利用于unordered_map

以上就是c++++中如何定义一个哈希函数用于自定义类型的unordered_map_c++自定义哈希函数编写方法的详细内容,更多请关注php中文网其它相关文章!

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号