新闻中心

c++怎么自定义std::unordered_map的哈希函数_c++自定义哈希函数实现方法

2025-11-11
浏览次数:
返回列表
要使用自定义类型作为std::unordered_map的键,需提供哈希函数和相等比较操作。1. 定义operator==用于比较;2. 特化std::hash或传入自定义哈希仿函数;3. 推荐使用黄金比例常数进行哈希值组合以减少冲突,确保相同对象哈希值相同且分布均匀。

c++怎么自定义std::unordered_map的哈希函数_c++自定义哈希函数实现方法

在C++中,std::unordered_map 默认支持基本类型(如 int、string)作为键,但如果想使用自定义类型(比如结构体或类)作为键,就需要提供一个自定义的哈希函数。这是因为 unordered_map 依赖哈希来存储和查找元素,而标准库不知道如何对用户定义类型进行哈希。

1. 自定义哈希函数的方法

要让自定义类型作为 std::unordered_map 的键,需要做两件事:

  • 实现一个哈希计算函数,继承或特化 std::hash
  • 确保该类型支持 == 比较操作(用于处理哈希冲突)

2. 特化 std::hash 模板

以一个简单的结构体为例:

struct Point {
    int x, y;
    bool operator==(const Point& other) const {
        return x == other.x && y == other.y;
    }
};

现在为 Point 类型特化 std::hash

namespace std {
    template<>
    struct hash<Point> {
        size_t operator()(const Point& p) const {
            // 使用哈希组合技巧:将两个整数哈希值混合
            return hash<int>{}(p.x) ^ (hash<int>{}(p.y) << 1);
        }
    };
}

这样就可以将 Point 用作 unordered_map 的键:

unordered_map<Point, string> locationMap;
locationMap[{1, 2}] = "origin";
</font>

3. 使用自定义哈希仿函数(不修改 std 命名空间)

如果你不想或不能特化 std::hash(比如涉及第三方类型),可以传入自定义哈希函数作为模板参数:

千鹿Pr助手 千鹿Pr助手

智能Pr插件,融入众多AI功能和海量素材

千鹿Pr助手 128 查看详情 千鹿Pr助手
struct PointHash {
    size_t operator()(const Point& p) const {
        return hash<int>{}(p.x) ^ (hash<int>{}(p.y) << 1);
    }
};

// 使用方式
unordered_map<Point, string, PointHash> locationMap;
</font>

这种写法更安全,避免了在 std 命名空间中添加特化可能导致的问题。

4. 哈希组合建议

上面用到的异或加移位方法简单但不够健壮(可能造成哈希冲突)。推荐使用更可靠的组合方式:

size_t operator()(const Point& p) const {
    size_t h1 = hash<int>{}(p.x);
    size_t h2 = hash<int>{}(p.y);
    // 使用一种标准的哈希合并方法
    return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
}

其中 0x9e3779b9 是黄金比例常数,常用于提升哈希分布均匀性。

基本上就这些。只要提供哈希计算和相等比较,就能让任意类型成为 unordered_map 的键。关键是保证相同对象产生相同哈希值,不同对象尽量减少冲突。

以上就是c++++怎么自定义std::unordered_map的哈希函数_c++自定义哈希函数实现方法的详细内容,更多请关注其它相关文章!


# 如果你  # 快消品营销推广分析  # 东营网站推广微忻hfqjwl下拉  # seo主要流量来自什么页面  # 莱州网站建设效果  # 含广告的网站怎么做推广  # 江干区百度网站优化公司  # 手机卖场关键词优化排名  # seo运营需要注意什么  # 富民网站建设平台  # 自己建网站自己推广怎么弄  # 相关文章  # c++  # 文本文件  # 如何用  # 多线程  # 尼克  # 推荐使用  # 如何实现  # 特化  # 自定义  # red  # 标准库 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: Windows10怎么开启夜间模式 Windows10系统设置调整色温与亮度缓解夜间用眼疲劳【教程】  Django表单提交验证失败后保持字段值不刷新  荣耀Play7TPro怎样在信息App置顶客服对话_iPhone荣耀Play7TPro信息App置顶客服对话【优先查看】  夸克浏览器桌面版同步不了书签怎么处理 夸克浏览器跨设备同步异常解决方案  谷歌推RCS信息存档功能:公司可监控员工私密信息!  Mudbox图层蒙版怎么用_Mudbox图层蒙版数字雕刻应用技巧  Pandas DataFrame 高效批量赋值:告别循环与笛卡尔积误区  在WordPress中通过REST API获取BasicAuth保护的远程文章  谷歌浏览器最新官方入口链接 谷歌浏览器网页版官网导航  Go语言中Map存储的结构体如何调用指针方法:深入解析与实践  探索高级语言到原生C/C++的转译:挑战与内存管理策略  CSS Flexbox如何实现多行排列_flex-wrap wrap自动换行显示  晋江读书网页版在线登录 晋江读书电脑版官网  智慧团建扫码登录入口 智慧团建扫码登录入口官网版​  2026年CSGO开箱网站推荐 CSGO开箱平台精选  蛙漫2日版入口 WAMAN2(日版)无删减漫画官网链接  “在文档元素之后找到了标记”是什么错误? 检查并修复XML中多个根元素的3个方法  Excel中VLOOKUP的第四个参数是干什么用的_Excel VLOOKUP第四参数作用解析  PrimeNG Sidebar背景色自定义指南:CSS覆盖与主题化实践  163邮箱网页版入口导航平台 163邮箱网页版登录入口官网导航  响应式图片在网页设计中的正确实现方法  如何在复杂的电商平台中优雅地管理共享资源并确保正确重定向,使用spryker-shop/resource-share-page模块助你一臂之力  蛙漫画网页版全站入口 蛙漫热门作品免费浏览  Composer的 "licenses" 命令如何帮助你遵守开源协议_检查项目依赖的许可证合规性  在J*a中如何隐藏复杂性_使用门面模式组织对象交互  html网页设计源代码怎么运行_运行html网页设计源代码步骤【指南】  Golang如何实现容器化日志收集与分析_Golang容器日志收集分析方法  4399体育竞技小游戏_4399小游戏赛事入口  解决移动端滚动问题的overflow属性应用指南  Yandex搜索引擎官网入口_俄罗斯Yandex免登录一键直达  Django表单验证失败时保留用户输入数据的最佳实践  QQ邮箱官方网页版登录 QQ邮箱个人邮箱快速访问  steam官方入口大全 steam账号注册及操作指南  天猫2025双十一0点秒杀攻略 天猫爆款抢购时间  印象笔记如何设离线包出差查阅_印象笔记设离线包出差查阅【离线阅读】  Discord Slash 命令响应超时问题的异步解决方案  Vue.js 图片显示异常排查:理解应用挂载范围与DOM ID唯一性  动漫花园资源网使用步骤_动漫花园资源网下载流程  优化Log4j2控制台输出性能:解决异步日志瓶颈  c++如何使用std::memory_order控制原子操作顺序_c++ C++11内存模型详解  批改网学生版PC登录 批改网官网登录系统入口  漫蛙漫画官方首页 漫蛙2漫画在线阅读入口  在Go Martini框架中高效服务动态生成图像的实践指南  将HTML动态表格多行数据保存到Google Sheet的教程  J*a最大堆Heapify方法修复:索引计算与边界条件深度解析  使用CSS更改登录屏幕输入框中PNG图标颜色的策略与局限性  CSS图片焦点样式实现教程:理解与应用tabindex属性  BetterDiscord插件中安全更新用户简介的实践指南  Yandex官方入口网址 Yandex俄罗斯搜索引擎最新在线地址  J*aScript中针对特定容器内图片动画的实现教程 

搜索