news 2026/4/15 8:54:10

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/15 3:42:41

AList多平台一键部署指南:新手也能轻松搭建个人云盘

AList多平台一键部署指南&#xff1a;新手也能轻松搭建个人云盘 【免费下载链接】alist 项目地址: https://gitcode.com/gh_mirrors/alis/alist 在数字化时代&#xff0c;我们的文件往往分散在不同的云存储平台中&#xff0c;阿里云盘、百度网盘、OneDrive等各有千秋&a…

作者头像 李华
网站建设 2026/4/11 4:50:05

Wish跨境电商平台研究指南:十款实用工具助力市场与算法分析

在专注于移动端与算法驱动的全球电商领域&#xff0c;Wish平台以其独特的推荐机制、极具价格竞争力的商品和庞大的新兴市场用户基础&#xff0c;成为观察兴趣电商、下沉市场消费及算法治理的典型样本。该平台为研究者理解基于行为的商品推荐、超低价跨境供应链及特定用户群体的…

作者头像 李华
网站建设 2026/4/11 4:59:47

终极指南:如何使用ApiTestEngine快速构建自动化API测试

终极指南&#xff1a;如何使用ApiTestEngine快速构建自动化API测试 【免费下载链接】httprunner 项目地址: https://gitcode.com/gh_mirrors/ap/ApiTestEngine ApiTestEngine是一个开源的API测试引擎&#xff0c;专为开发者和测试工程师设计&#xff0c;旨在提供高效、…

作者头像 李华
网站建设 2026/4/14 2:22:21

从蓝队打杂到日薪 2700,护网 5 个核心工具让甲方主动抛橄榄枝

一、护网第 3 天&#xff0c;我因为工具用得好&#xff0c;被甲方单独加了 500 日薪 去年第一次参加护网&#xff0c;我跟个无头苍蝇似的 —— 甲方让 3 小时内梳理 100 台服务器资产&#xff0c;别人用 Excel 手动录 IP&#xff0c;我用 Nmap 批量处理脚本&#xff0c;1 小时…

作者头像 李华
网站建设 2026/4/11 1:10:09

PlayCover完整指南:在Mac上运行iOS应用的终极配置方案

PlayCover完整指南&#xff1a;在Mac上运行iOS应用的终极配置方案 【免费下载链接】PlayCover Community fork of PlayCover 项目地址: https://gitcode.com/gh_mirrors/pl/PlayCover 本指南将详细介绍如何在Apple Silicon Mac设备上通过PlayCover运行iOS应用&#xff0…

作者头像 李华
网站建设 2026/4/11 20:00:14

如何快速加速GitHub访问:开发者的完整解决方案指南

GitHub作为全球最大的代码托管平台&#xff0c;访问速度缓慢和图片无法加载的问题长期困扰着国内开发者。通过系统配置优化方案&#xff0c;可以显著提升GitHub的访问体验&#xff0c;让代码浏览和项目协作更加高效流畅。本指南将为您提供简单易行的GitHub加速方法。 【免费下载…

作者头像 李华