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

使用std::hash以pair为键调用emplace时出现函数不匹配错误

问题根源

C++标准库没有为std::pair<T1, T2>提供默认的std::hash特化,你直接用std::hash<Pair>作为unordered_map的哈希函数模板参数,编译器找不到合法的哈希函数类型,导致整个容器定义无效,最终emplace调用时出现匹配错误。

解决方法

有两种常用方案可以修复这个问题:

方案一:自定义哈希函数结构体

直接定义一个专门用于哈希std::pair<std::string_view, std::string_view>的结构体,代替std::hash<Pair>:

class A
{
    using Pair = std::pair<std::string_view, std::string_view>;
    
    // 自定义哈希函数
    struct PairHash {
        size_t operator()(const Pair& p) const {
            // 组合两个string_view的哈希值,也可以用更均匀的组合逻辑
            size_t h1 = std::hash<std::string_view>{}(p.first);
            size_t h2 = std::hash<std::string_view>{}(p.second);
            return h1 ^ (h2 << 1);
        }
    };

    // 使用自定义哈希函数替换原来的MsrPairHash
    std::unordered_map<Pair, std::shared_ptr<A>, PairHash> mp;

public:
    void foo(std::string_view a, std::string_view b, std::shared_ptr<A> ptr)
    {
        mp.emplace(std::make_pair(a, b), std::move(ptr));
        // 也可以保持原来的初始化方式:mp.emplace({a, b}, std::move(ptr));
    }
};

方案二:特化std::hash

在std命名空间内为std::pair<std::string_view, std::string_view>提供std::hash的特化(仅当类型是标准库类型的组合时,这种特化符合标准要求):

// 放在全局作用域或合适的头文件中
namespace std {
    template<>
    struct hash<std::pair<std::string_view, std::string_view>> {
        size_t operator()(const std::pair<std::string_view, std::string_view>& p) const {
            size_t h1 = hash<std::string_view>{}(p.first);
            size_t h2 = hash<std::string_view>{}(p.second);
            // 推荐使用更均匀的哈希组合方式,减少冲突概率
            return h1 * 31 + h2;
        }
    };
}

class A
{
    using Pair = std::pair<std::string_view, std::string_view>;
    using MsrPairHash = std::hash<Pair>; // 现在特化已存在,可正常使用
    std::unordered_map<Pair, std::shared_ptr<A>, MsrPairHash> mp;

public:
    void foo(std::string_view a, std::string_view b, std::shared_ptr<A> ptr)
    {
        mp.emplace({a, b}, std::move(ptr));
    }
};
额外注意事项

使用std::string_view作为unordered_map的键时,必须保证string_view指向的原始字符串生命周期长于unordered_map,否则会出现悬垂引用,导致程序出现未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:50:42