news 2026/4/23 18:52:46

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/4/23 10:47:00

震惊!又一本顶刊被剔除TOP!

本期解刊《Environmental Pollution》《Environmental Pollution》是环境领域的老牌二区期刊&#xff0c;近几年EP发展不算太快&#xff08;前期与总环不相上下&#xff0c;后来慢慢被拉开差距了&#xff09;&#xff0c;但其在行业内的认可度、含金量还是比较高的&#xff08;…

作者头像 李华
网站建设 2026/4/23 10:46:01

排水管网智慧感知与运维管理系统方案

随着城市化进程加速和极端天气频发&#xff0c;城市排水管网面临严峻挑战&#xff1a;传统人工巡检效率低、数据滞后&#xff0c;难以实时掌握管网运行状态&#xff1b;暴雨内涝、管道破裂、泵站故障等事件频发&#xff0c;导致城市运行受阻、经济损失严重&#xff1b;同时&…

作者头像 李华
网站建设 2026/4/23 10:44:15

.net4和core的差异与iis部署差异

在.NET 生态中&#xff0c;.NET 4.5&#xff08;.NET Framework&#xff09;可以 “不发布直接部署”&#xff0c;但 **.NET 6&#xff08;.NET Core / 跨平台系列&#xff09;无法绕过发布流程直接部署 **&#xff0c;核心原因是两者的运行时模型、编译方式和 IIS 集成逻辑存在…

作者头像 李华
网站建设 2026/4/22 13:27:10

终极LaTeX论文清理方案:轻松应对arXiv提交挑战

终极LaTeX论文清理方案&#xff1a;轻松应对arXiv提交挑战 【免费下载链接】arxiv-latex-cleaner arXiv LaTeX Cleaner: Easily clean the LaTeX code of your paper to submit to arXiv 项目地址: https://gitcode.com/gh_mirrors/ar/arxiv-latex-cleaner arXiv LaTeX …

作者头像 李华
网站建设 2026/4/23 13:35:27

路径质量 + 计算速度双提升!PowerMill 2025 下载安装步骤五轴加工全解析

简介 PowerMill 2025 是 最新一代 CAM 软件&#xff0c;专为汽车、精密模具等领域的复杂零件高速加工和五轴联动加工场景设计。针对这类场景中 “编程效率低、路径精度差、程序管理混乱” 的痛点&#xff0c;软件重点提升三大核心能力&#xff1a;一是刀具路径质量&#xff0c…

作者头像 李华
网站建设 2026/4/23 12:10:18

国产云桌面产品中哪些?哪家比较好用?

在数字化转型日益深入的今天&#xff0c;云桌面技术已成为政府、金融、医疗、能源等行业实现高效办公、数据安全与IT集中管理的重要工具。随着信息技术应用创新产业的发展&#xff0c;国产化云桌面解决方案备受关注。本文将为您梳理当前国产云桌面市场的主要产品特点&#xff0…

作者头像 李华