news 2026/6/10 5:00:57

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/6/10 17:30:59

工业采集神器!4/6/8/12路可选,16位AD高精度拿下4-20mA/0-10V

4/6/8/12 16位AD高精度采集模块是一种工业级的模数转换数据采集设备&#xff0c;核心是搭载16位分辨率的AD(模数)转换芯片&#xff0c;且提供4、6、8、12路可选的信号采集通道&#xff0c;主要用于将工业现场的模拟信号(如电压、电流、温度、压力等传感器输出信号)高精度转换为…

作者头像 李华
网站建设 2026/6/10 10:31:47

SpringBoot 实战:从 0 到 1 搭建企业级后端应用

一、前言&#xff1a;SpringBoot 为何成为后端开发的 “事实标准” 在传统 Spring 开发时代&#xff0c;开发者需要面对海量 XML 配置、依赖版本冲突、服务器部署繁琐三大痛点。SpringBoot 的出现&#xff0c;以 **“约定优于配置”为核心思想&#xff0c;通过自动配置机制、场…

作者头像 李华
网站建设 2026/6/9 20:27:21

覆盖全场景·采集无误差:16位AD高精度模块的应用赋能手册

16位AD高精度采集模块的应用非常广泛&#xff0c;它是连接工业现场模拟信号与数字控制系统的核心桥梁&#xff0c;凭借16位的高分辨率、多通道灵活性和工业级稳定性&#xff0c;几乎覆盖了工业自动化、物联网、精密测量、智能监测等多个核心领域。一、应用场景 1.工业自动化与智…

作者头像 李华
网站建设 2026/6/10 15:48:24

Farfalle实战指南:构建本地AI搜索引擎的完整方案

Farfalle实战指南&#xff1a;构建本地AI搜索引擎的完整方案 【免费下载链接】farfalle &#x1f50d; ai search engine - run local or cloud language models 项目地址: https://gitcode.com/GitHub_Trending/fa/farfalle 真实场景&#xff1a;传统搜索的局限性 在日…

作者头像 李华
网站建设 2026/6/10 15:03:53

流量突然提升 100 倍,LLM Agent 和 Workflow,到底怎么选?

最近看到群里同学们在讨论&#xff1a;“系统要加大模型&#xff0c;workflow 还能用吗&#xff1f;还是要上 Agent&#xff1f;” 表面上是技术选型&#xff0c;实际上是“你希望机器帮你做步骤&#xff0c;还是帮你思考”。 大模型最早期&#xff1a;只是一个“聪明的接口”…

作者头像 李华
网站建设 2026/6/10 5:30:32

深入理解 iPhone 文件管理,从沙盒结构到开发调试的多工具协同实践

在很多开发者眼中&#xff0c;iPhone 文件管理 似乎只是“看看 Documents 里有什么文件”&#xff0c;但在真实的开发、测试与问题排查过程中&#xff0c;文件系统往往是最容易被忽略、却又最容易出问题的一环。 无论是以下场景&#xff1a; App 占用空间越来越大图片、音频、视…

作者头像 李华