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

使用std::pair<ndmInst*, bool>作为std::unordered_map键编译错误求助

解决std::unordered_map编译错误的思路

问题代码

// 注意:cmpClkgate类定义在unordered_map实例化之后,顺序错误
std::unordered_map<std::pair<ndmInst*, bool>, std::vector<slmEndpointsTimingInfo>, cmpClkgate> clkgateEndpointsMap;

slmEndpointsTimingInfo endpointsInfoObj;
std::pair<ndmInst*, bool> p = std::make_pair(clkFaninInsts[0], isFallEdgeClk);
clkgateEndpointsMap[p].push_back(endpointsInfoObj); //slmPMUEPAsgnStrgy.cc:125

class cmpClkgate {
  public:
  bool operator()(const std::pair<ndmInst*, bool>& p1, const std::pair<ndmInst*, bool>& p2) const {    // this slmPMUEPAsgnStrgy.cc:81
    if (p1.first != p2.first) {
      return p1.first < p2.first;
    }
    return p1.second < p2.second;
  }
};

编译错误信息

/depotbld/RHEL7.0/gcc-9.5.0/include/c++/9.5.0/bits/hashtable_policy.h: In instantiation of ‘std::__detail::_Hash_code_base<...>’:
...
/depotbld/RHEL7.0/gcc-9.5.0/include/c++/9.5.0/bits/hashtable_policy.h:1382:16: error: static assertion failed: hash function must be invocable with an argument of key type
 1382 |  static_assert(__is_invocable<const _H1&, const _Key&>{},
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/depotbld/RHEL7.0/gcc-9.5.0/include/c++/9.5.0/bits/hashtable_policy.h:1384:16: error: no match for call to ‘(const dc::cmpClkgate) (const std::pair<ndmInst*, bool>&)’
 1384 |  return _M_h1()(__k);
      |         ~~~~~~~^~~~~
slmPMUEPAsgnStrgy.cc:81:8: note: candidate: ‘bool dc::cmpClkgate::operator()(const std::pair<ndmInst*, bool>&, const std::pair<ndmInst*, bool>&) const’
   81 |   bool operator()(const std::pair<ndmInst*, bool>& p1, const std::pair<ndmInst*, bool>& p2) const {
      |        ^~~~~~~~
slmPMUEPAsgnStrgy.cc:81:8: note:   candidate expects 2 arguments, 1 provided

错误原因分析

  • 模板参数类型混淆:std::unordered_map的第三个模板参数要求是哈希函数(Hash),该函数需要接受单个Key类型参数,返回size_t类型的哈希值;但你传入的cmpClkgate是一个二元比较函数(用于判断两个键的大小/相等性,是std::map的第三个参数类型),它的operator()需要两个参数,完全不符合哈希函数的要求。
  • 类定义顺序错误:cmpClkgate类的定义在unordered_map实例化之后,编译器在实例化时无法识别该类型,这也是潜在问题。

解决方案

步骤1:定义正确的哈希函数

针对std::pair<ndmInst*, bool>类型,实现一个哈希函数类,将pair的两个成员的哈希值组合起来:

struct HashClkgateKey {
    size_t operator()(const std::pair<ndmInst*, bool>& key) const {
        // 分别计算指针和bool的哈希值,再组合避免冲突
        size_t hash1 = std::hash<ndmInst*>()(key.first);
        size_t hash2 = std::hash<bool>()(key.second);
        return hash1 ^ (hash2 << 1);
    }
};

步骤2:调整unordered_map的模板参数

std::unordered_map的第四个参数是相等判断函数(Pred),把cmpClkgate放到这个位置(若默认的std::equal_to<std::pair<...>>能满足需求,也可省略)。同时确保类的定义在实例化之前:

// 先定义哈希函数和比较函数
struct HashClkgateKey {
    size_t operator()(const std::pair<ndmInst*, bool>& key) const {
        size_t hash1 = std::hash<ndmInst*>()(key.first);
        size_t hash2 = std::hash<bool>()(key.second);
        return hash1 ^ (hash2 << 1);
    }
};

class cmpClkgate {
  public:
  bool operator()(const std::pair<ndmInst*, bool>& p1, const std::pair<ndmInst*, bool>& p2) const {
    if (p1.first != p2.first) {
      return p1.first < p2.first;
    }
    return p1.second < p2.second;
  }
};

// 实例化unordered_map:第三个参数是哈希函数,第四个是相等判断函数
std::unordered_map<std::pair<ndmInst*, bool>, std::vector<slmEndpointsTimingInfo>, HashClkgateKey, cmpClkgate> clkgateEndpointsMap;

步骤3:验证相等判断函数的必要性

如果你的相等判断逻辑和std::pair默认的相等判断(两个成员分别相等)一致,可省略第四个参数,直接使用默认实现:

std::unordered_map<std::pair<ndmInst*, bool>, std::vector<slmEndpointsTimingInfo>, HashClkgateKey> clkgateEndpointsMap;

额外注意事项

  • 哈希函数的设计要尽量减少冲突,上面的移位异或只是简单实现,也可以用hash1 * 31 + hash2这类更稳定的组合方式。
  • std::hash对指针的实现是直接取地址的哈希值,一般可满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 17:18:13