自定义std::hash<A>遇const限定符丢失错误,求正确实现方式
自定义std::hash特化时的const限定符错误解决方法
你在为自定义类A实现std::hash特化,想要用于std::unordered_set和std::unordered_map时,遇到了编译错误:expression having type 'const_Hasher' would lose some const-volatile qualifiers in order to call,用Visual Studio 2022编译会出现3个相关错误。移除const修饰反而引发其他问题,下面是错误原因分析和正确实现方式:
你的MCVE代码
#include <unordered_set> class A { int num; public: A(int num) : num(num) {} int getNum() const { return num; } bool operator==(const A& other) const { return num == other.getNum(); } }; namespace std { template<> struct hash<A> { size_t operator()(const A& key) { return key.getNum(); } }; } int main() { std::unordered_set<A> mySet; mySet.emplace(1); return 0; }
错误原因
std::unordered_set内部会以const哈希对象的方式调用operator(),但你实现的hash<A>::operator()没有添加const限定符。C++不允许通过const对象调用非const成员函数,因此编译器报错,提示调用时会丢失const-volatile限定符。
正确实现方法
只需要把hash<A>结构体中的operator()声明为const成员函数即可:
namespace std { template<> struct hash<A> { // 添加const限定符 size_t operator()(const A& key) const { return key.getNum(); } }; }
修正后的完整代码
#include <unordered_set> class A { int num; public: A(int num) : num(num) {} int getNum() const { return num; } bool operator==(const A& other) const { return num == other.getNum(); } }; namespace std { template<> struct hash<A> { size_t operator()(const A& key) const { return key.getNum(); } }; } int main() { std::unordered_set<A> mySet; mySet.emplace(1); return 0; }
额外注意事项
- 确保你的哈希函数生成的哈希值尽可能减少碰撞(当前示例直接返回int值对于简单类没问题,但复杂类需要结合多个成员变量计算更合理的哈希值)
- 必须保证类A的
operator==正确实现,这是unordered容器判断元素是否相等的依据,你当前的实现是正确的
内容的提问来源于stack exchange,提问作者Chandrachur Mukherjee
相关产品推荐
相关产品推荐

