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

为何代码触发编译器错误:指定哈希不满足Hash要求?

unordered_set自定义哈希不满足Hash要求的编译错误解决

问题背景

以下是代码实现:

auto myComp = []( std::array<const string, 3> &a, std::array<const string, 3> &b )
{
    if ( a[0] == b[0] && a[1] == b[1] && a[2] == b[2] ) {
        return true;
    } else {
        return false;
    }
};
auto myHash = []( std::array<const string, 3> &a )
{
    return std::hash<std::string>()( a[0] )
    ^ std::hash<std::string>()( a[1] )
    ^ std::hash<std::string>()( a[2] );
};
std::unordered_set<std::array<const string, 3>, decltype( myHash ), decltype( myComp )> unordSet( 16, myHash, myComp );

编译时触发错误:

MacOSX15.1.sdk/usr/include/c++/v1/__hash_table:607:17 Static assertion failed due to requirement 'integral_constant<bool, false>::value': the specified hash does not meet the Hash requirements

查看哈希检查定义:

#ifndef _LIBCPP_CXX03_LANG
template <class _Key, class _Hash>
using __check_hash_requirements _LIBCPP_NODEBUG =
    integral_constant<bool,
                      is_copy_constructible<_Hash>::value && is_move_constructible<_Hash>::value &&
                          __invokable_r<size_t, _Hash, _Key const&>::value >;
#endif

经排查,__invokable_r<size_t, _Hash, _Key const&>::value条件不满足。


解决方法

1. 修改哈希与比较函数的参数为const引用

unordered_set在调用哈希、比较函数时,会传递const修饰的Key类型,原代码中的lambda参数仅接受非const引用,无法匹配调用要求,这是导致断言失败的核心原因。

修改后的函数如下:

// 相等性比较函数:参数改为const引用
auto myComp = [](const std::array<const std::string, 3>& a, const std::array<const std::string, 3>& b)
{
    return a[0] == b[0] && a[1] == b[1] && a[2] == b[2];
};

// 哈希函数:参数改为const引用
auto myHash = [](const std::array<const std::string, 3>& a)
{
    return std::hash<std::string>()(a[0])
           ^ std::hash<std::string>()(a[1])
           ^ std::hash<std::string>()(a[2]);
};

2. 优化哈希函数(可选但推荐)

原代码使用异或(^)组合哈希值容易引发哈希碰撞(不同元素生成相同哈希值),推荐使用更稳健的组合方式,比如:

auto myHash = [](const std::array<const std::string, 3>& a)
{
    size_t hash_val = std::hash<std::string>()(a[0]);
    // 用质数乘法分散哈希值,减少碰撞概率
    hash_val = hash_val * 31 + std::hash<std::string>()(a[1]);
    hash_val = hash_val * 17 + std::hash<std::string>()(a[2]);
    return hash_val;
};

3. 完整可编译代码

#include <unordered_set>
#include <array>
#include <string>
#include <functional>

int main()
{
    auto myComp = [](const std::array<const std::string, 3>& a, const std::array<const std::string, 3>& b)
    {
        return a[0] == b[0] && a[1] == b[1] && a[2] == b[2];
    };

    auto myHash = [](const std::array<const std::string, 3>& a)
    {
        size_t hash_val = std::hash<std::string>()(a[0]);
        hash_val = hash_val * 31 + std::hash<std::string>()(a[1]);
        hash_val = hash_val * 17 + std::hash<std::string>()(a[2]);
        return hash_val;
    };

    std::unordered_set<std::array<const std::string, 3>, decltype(myHash), decltype(myComp)> unordSet(16, myHash, myComp);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 06:05:20