You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为自定义Vec2实现带max参数的哈希函数时unordered_map报错

自定义带参数哈希函数适配std::unordered_map的问题解决

错误原因分析

  1. 模板参数类型不匹配:std::unordered_map的第三个模板参数要求是哈希函数的类型,但你直接传入了HashVec2int{300}(一个对象实例),编译器因此报错"expected a type, got 'HashVec2int{300u}'"。
  2. 哈希函数与key类型不匹配:你的unordered_map的key是std::pair<iVec2, iVec2>,但HashVec2int的operator()仅支持Vec2<int>类型,无法处理pair对象,导致后续operator[]调用失败。
  3. 哈希结构体构造函数未启用:你注释掉了HashVec2int的构造函数,无法正确初始化maximum成员变量。

修正方案

  1. 启用HashVec2int的构造函数,确保能传入并保存maximum参数。
  2. 针对std::pair<iVec2, iVec2>类型实现哈希函数,内部复用HashVec2int来分别哈希两个Vec2成员,再合并哈希值。
  3. 在创建unordered_map时,模板参数填写哈希函数类型,通过构造函数传入带参数的哈希实例。

修正后的完整代码

#include <iostream>
#include <unordered_map>
#include <utility>
#include <stdint.h>

template <class T>
struct Vec2 
{
    T x, y;
    Vec2()           : x(0) , y(0)  { };
    Vec2(T xn, T yn) : x(xn), y(yn) { };

    bool operator==(const Vec2& vec) const 
    {
        return (x == vec.x) && (y == vec.y); 
    }
};

struct HashVec2int
{
    const uint32_t maximum;

    // 启用构造函数,初始化maximum参数
    HashVec2int(uint32_t m) : maximum(m) { }

    std::size_t operator()(const Vec2<int>& vec) const
    { 
        // 转换为std::size_t避免溢出
        return static_cast<std::size_t>(vec.x) * maximum + vec.y; 
    }
};

// 针对std::pair<iVec2, iVec2>的哈希函数
struct HashPairVec2
{
    HashVec2int vec_hash;

    // 传入max_x参数,初始化内部的HashVec2int
    HashPairVec2(uint32_t max_x) : vec_hash(max_x) {}

    std::size_t operator()(const std::pair<Vec2<int>, Vec2<int>>& p) const
    {
        // 合并两个Vec2的哈希值,使用质数31来减少哈希碰撞
        std::size_t h1 = vec_hash(p.first);
        std::size_t h2 = vec_hash(p.second);
        return h1 * 31 + h2;
    }
};

int main() {

    using iVec2 = Vec2<int>;
    // 模板参数填哈希类型HashPairVec2,构造时传入带参数的哈希实例
    std::unordered_map<std::pair<iVec2, iVec2>, float, HashPairVec2> umap{HashPairVec2(300)};

    umap[std::make_pair(iVec2(1, 2), iVec2(2, 3))] = 3.14f;
    
    std::cout << umap[std::make_pair(iVec2(1, 2), iVec2(2, 3))];
    
    return 0;
}

额外说明

  • 如果你的实际需求是将单个Vec2<int>作为unordered_map的key,只需调整unordered_map的模板参数和构造方式:
    std::unordered_map<iVec2, float, HashVec2int> umap{HashVec2int(300)};
    
  • 合并哈希值时使用质数(如31、101)是为了降低哈希碰撞的概率,你可以根据实际场景调整。

内容的提问来源于stack exchange,提问作者gournge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:51:16