news 2026/5/11 7:20:23

boost库中boost::hash_combine和boost::hash_range使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
boost库中boost::hash_combine和boost::hash_range使用

boost::hash_combine

1.boost::hash_combine的作用

boost::hash_combine是 Boost 库中用于组合多个哈希值的辅助函数。它通常用于自定义类型(struct/class)的哈希函数,用于像std::unordered_mapstd::unordered_set这样的哈希容器。

如果有一个结构体包含多个成员,想根据这些成员生成一个哈希值,单纯地对每个成员哈希再简单相加可能冲突多,hash_combine提供了一种较好的组合方式


2.boost::hash_combine的实现原理

在 Boost 1.55 中,它大致定义如下:

template<classT>inlinevoidhash_combine(std::size_t&seed,constT&v){std::hash<T>hasher;seed^=hasher(v)+0x9e3779b9+(seed<<6)+(seed>>2);}

解释:

  1. seed是之前已有的哈希值,可以是初始值0
  2. v是当前需要组合进哈希的值。
  3. 0x9e3779b9是黄金比例常数(232/ϕ2^{32}/\phi232/ϕ),用于增加哈希的均匀性。
  4. (seed<<6) + (seed>>2)是为了混合之前的哈希值,减少冲突。
  5. ^=将新值与已有的seed结合起来。

这种组合方式被证明对小型结构体哈希效果不错。


3. 基本使用方法

假设我们有一个自定义类型Point

#include<boost/functional/hash.hpp>#include<unordered_set>#include<iostream>structPoint{intx,y;booloperator==(constPoint&other)const{returnx==other.x&&y==other.y;}};// 自定义哈希函数structPointHash{std::size_toperator()(constPoint&p)const{std::size_t seed=0;boost::hash_combine(seed,p.x);boost::hash_combine(seed,p.y);returnseed;}};intmain(){std::unordered_set<Point,PointHash>s;s.insert({1,2});s.insert({3,4});for(constauto&p:s)std::cout<<"("<<p.x<<","<<p.y<<")\n";}

说明:

  • 先定义一个seed(初始为0)。
  • 对每个成员调用boost::hash_combine(seed, value)
  • 最终返回seed作为整体的哈希值。

4. 组合多个成员的示例

假设结构体更复杂:

structPerson{std::string name;intage;doubleheight;};structPersonHash{std::size_toperator()(constPerson&p)const{std::size_t seed=0;boost::hash_combine(seed,p.name);boost::hash_combine(seed,p.age);boost::hash_combine(seed,p.height);returnseed;}};
  • boost::hash_combine可以处理任何支持std::hash的类型。
  • 可以无限次组合多个成员。

5. 注意事项

  1. boost::hash_combine并不会保证完全无冲突,只是降低冲突概率。
  2. 对浮点数组合时,注意可能的精度问题。
  3. 对自定义类成员递归组合即可。

6. 总结

  • boost::hash_combine(seed, value)是组合哈希值的标准方法。
  • 常用于自定义类型哈希函数。
  • 使用模式:
size_t seed=0;hash_combine(seed,member1);hash_combine(seed,member2);hash_combine(seed,member3);returnseed;

boost::hash_range

1. 概述

boost::hash_range是 Boost 库中boost::functional::hash模块提供的一个函数模板,用于对一段区间(range)中的元素生成哈希值。它常用于需要对容器内容进行哈希的场景,比如将std::vectorstd::list等放入unordered_mapunordered_set时。

#include<boost/functional/hash.hpp>

2. 函数原型

namespaceboost{template<classInputIt>std::size_thash_range(InputIt first,InputIt last);}
  • 模板参数
    InputIt:输入迭代器类型,通常为容器的迭代器。

  • 参数

    • first:区间起始迭代器(包含)
    • last:区间结束迭代器(不包含)
  • 返回值
    返回std::size_t类型的哈希值。

特点

  • 支持任意类型的容器,只要元素类型可哈希(可以被boost::hash<T>支持)。
  • 哈希结果会考虑元素顺序,所以{1,2,3}{3,2,1}的哈希值不同。
  • 可用于自定义容器作为键的哈希函数。

3. 内部原理

hash_range的核心思路是对区间内的每个元素进行哈希,并通过一个迭代式的合并算法得到最终哈希值,类似下面的伪代码:

std::size_t seed=0;for(autoit=first;it!=last;++it){seed^=boost::hash_value(*it)+0x9e3779b9+(seed<<6)+(seed>>2);}returnseed;

其中:

  • 0x9e3779b9是黄金分割常数,用于减少冲突。
  • seed << 6seed >> 2是位混合操作。
  • 每个元素的哈希值会与前一个累积的seed混合,从而生成一个整体哈希。

4. 使用示例

示例 1:对std::vector<int>生成哈希

#include<iostream>#include<vector>#include<boost/functional/hash.hpp>intmain(){std::vector<int>v={1,2,3,4,5};std::size_t h=boost::hash_range(v.begin(),v.end());std::cout<<"Hash of vector: "<<h<<std::endl;return0;}

输出类似:

Hash of vector: 1234567890

示例 2:在unordered_map中使用容器作为 key

#include<iostream>#include<vector>#include<unordered_map>#include<boost/functional/hash.hpp>structVectorHash{std::size_toperator()(conststd::vector<int>&v)const{returnboost::hash_range(v.begin(),v.end());}};intmain(){std::unordered_map<std::vector<int>,std::string,VectorHash>map;map[{1,2,3}]="Hello";map[{4,5,6}]="World";std::vector<int>key={1,2,3};std::cout<<"Value: "<<map[key]<<std::endl;// 输出 Helloreturn0;}

解释

  • 自定义VectorHash作为哈希函数。
  • boost::hash_range将整个 vector 的内容转换为单一哈希值。

示例 3:哈希自定义结构体内的区间

#include<vector>#include<boost/functional/hash.hpp>structMyStruct{std::vector<int>data;booloperator==(constMyStruct&other)const{returndata==other.data;}};structMyStructHash{std::size_toperator()(constMyStruct&s)const{returnboost::hash_range(s.data.begin(),s.data.end());}};
  • 可与std::unordered_set<MyStruct, MyStructHash>搭配使用。
  • 注意:要同时实现operator==

5. 注意事项

  1. 顺序敏感
    hash_range会考虑元素顺序,因此{1,2,3}{3,2,1}哈希值不同。

  2. 元素类型必须可哈希
    boost::hash<T>必须支持容器内元素类型,否则编译报错。

  3. 自定义类型需实现boost::hash_valueoperator()
    否则hash_range无法生成哈希。

  4. 用于 unordered_map/set
    当容器或自定义类型作为键时非常有用,尤其是 vector/list 等非原生类型。

  5. 效率考虑
    对大型区间调用hash_range可能较慢,如果需要频繁查询,可以缓存哈希值。


6. 总结

boost::hash_range是一个非常方便的工具:

  • 对区间内容生成哈希值
  • 顺序敏感
  • 可以轻松用于自定义类型的哈希映射

它的常见应用场景:

  • std::vectorstd::list等容器放入unordered_map/unordered_set
  • 自定义结构体或组合类型哈希
  • 配合 Boost 提供的hash_combine与其他哈希策略进行复杂对象哈希

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 21:51:40

线性代数终极指南:5个快速掌握矩阵世界的完整路径

线性代数终极指南&#xff1a;5个快速掌握矩阵世界的完整路径 【免费下载链接】The-Art-of-Linear-Algebra Graphic notes on Gilbert Strangs "Linear Algebra for Everyone" 项目地址: https://gitcode.com/gh_mirrors/th/The-Art-of-Linear-Algebra 你是否…

作者头像 李华
网站建设 2026/5/9 10:57:10

红警、帝国老游戏无法在win10、win11下运行怎么办?针对红警、帝国之类老游戏适用WIN10和11的补丁cnc-ddraw7.1汉化版分享

cnc - ddraw7.1 汉化版堪称红警、帝国时代等老游戏在 Win10/Win11 系统上的 “复活神器”&#xff0c;能一键解决老游戏运行时的黑屏、卡顿、切屏闪退等兼容性问题&#xff0c;还支持高清、宽屏等适配现代显示器的优化功能 核心核心优势 功能亮点具体作用兼容性修复解决红警…

作者头像 李华
网站建设 2026/5/10 21:08:21

第4章 Spring AI 创建具有记忆能力的对话助理

4.4 案例&#xff1a;具有记忆能力的对话助理 在3.4.3小节中&#xff0c;我们介绍了如何使用 Assistant UI 简单实现通过页面与 DeepSeek API 进行对话。本节我们介绍如何使用 Assistant UI 和 Spring AI 实现一个有状态的智能对话系统。 (文末包含工程代码) 4.4.1 前端会话状…

作者头像 李华
网站建设 2026/5/10 12:57:01

高效文档自动化:Open XML SDK实战开发指南

高效文档自动化&#xff1a;Open XML SDK实战开发指南 【免费下载链接】Open-XML-SDK 项目地址: https://gitcode.com/gh_mirrors/ope/Open-XML-SDK 在现代企业应用中&#xff0c;Office文档处理已成为日常工作的重要环节。Open XML SDK作为微软官方推出的专业文档处理…

作者头像 李华
网站建设 2026/5/5 21:52:47

Balena Etcher镜像烧录工具完全指南:从零基础到精通

Balena Etcher是一款革命性的开源镜像烧录工具&#xff0c;专为简化操作系统镜像部署而生。无论您是需要制作树莓派启动盘&#xff0c;还是创建Windows恢复介质&#xff0c;Etcher都能在几分钟内帮您完成专业级烧录任务。 【免费下载链接】etcher Flash OS images to SD cards …

作者头像 李华
网站建设 2026/5/11 1:23:41

水经注万能地图下载器:一站式地图数据获取终极解决方案

水经注万能地图下载器&#xff1a;一站式地图数据获取终极解决方案 【免费下载链接】水经注万能地图下载器X3.0Build1469 水经注万能地图下载器 X3.0&#xff08;Build1469&#xff09;是一款功能强大的地图下载工具&#xff0c;集成了全球谷歌卫星地图下载、全球谷歌地球&…

作者头像 李华