news 2026/3/29 2:03:29

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/3/29 1:02:10

Calendar.js终极指南:零依赖JavaScript日历的快速上手指南

想要一个既强大又简单的JavaScript日历库吗&#xff1f;Calendar.js就是你的完美选择&#xff01;作为一款完全零依赖的响应式日历&#xff0c;它能让你在几分钟内就拥有专业级的日程管理功能。 【免费下载链接】Calendar.js &#x1f4c5; A javascript drag & drop event…

作者头像 李华
网站建设 2026/3/12 12:25:20

智慧楼宇中的工业网关发挥哪些作用

在智慧楼宇中&#xff0c;工业网关作为连接设备、网络与云平台的核心枢纽&#xff0c;通过协议转换、数据采集、边缘计算、安全通信和云平台对接等功能&#xff0c;实现了楼宇设备的智能化控制、能源的高效管理以及运维的自动化&#xff0c;具体作用如下&#xff1a;1. 协议转换…

作者头像 李华
网站建设 2026/3/27 21:36:13

OpenXR工具包深度实战:从性能瓶颈到流畅体验的技术突破

OpenXR工具包作为企业级VR应用开发的核心解决方案&#xff0c;在应对复杂渲染场景和跨平台兼容性挑战方面展现出突破性价值。该项目通过API层架构和模块化设计&#xff0c;为技术决策者提供了从性能优化到输入系统增强的完整技术栈。 【免费下载链接】OpenXR-Toolkit A collect…

作者头像 李华
网站建设 2026/3/26 12:29:24

.NET驾驭Word之力:基于规则自动生成及排版Word文档

MudTools.OfficeInterop 是一个针对 Microsoft Office 应用程序&#xff08;Excel、Word、PowerPoint、VBE&#xff09;的 .NET 封装库&#xff0c;旨在简化对 Office COM 组件的操作。它提供现代化、面向对象的 API 接口&#xff0c;使得开发者可以更轻松地处理 Office 文档。…

作者头像 李华
网站建设 2026/3/28 17:09:31

复杂知识简单学!Springboot加载配置文件源码分析

Springboot 加载配置文件源码分析 本文的分析是基于springboot 2.2.0.RELEASE。 本篇文章的相关源码位置:https://github.com/wbo112/blogdemo/tree/main/springbootdemo/springboot-profiles springboot加载配置文件如application.yml是通过org.springframework.boot.context.…

作者头像 李华
网站建设 2026/3/28 8:23:14

3分钟搞定抖音高清下载:douyin_downloader终极指南

还在为抖音精彩视频无法完美保存而烦恼&#xff1f;每次想要收藏喜欢的舞蹈教学、美食制作视频&#xff0c;却总被烦人的水印影响观感&#xff1f;douyin_downloader正是你需要的专业解决方案&#xff0c;让抖音无水印视频下载变得简单高效。 【免费下载链接】douyin_downloade…

作者头像 李华