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

编译器报错:std::variant作为unordered_map键无operator==匹配

问题原因及修复方案

核心问题1:operator==未声明为const成员函数

你的A和B类中定义的operator==不是const成员函数,而std::variant在执行相等比较时,会以const对象的身份调用内部类型的operator==,这导致编译器找不到匹配的const版本相等运算符,从而报错。

修复方法:给A和B的operator==加上const修饰,同时建议参数改用const引用避免拷贝:

// A类的operator==修改后
bool operator==(const A& a) const {
    return a.s == this->s;
}

// B类的operator==修改后
bool operator==(const B& b) const {
    return b.i == this->i;
}

核心问题2:std::variant<A,B>缺少hash特化(C++17及以下)

std::unordered_map要求键类型同时满足可哈希和可比较相等。你只特化了A和B的std::hash,但C++17及更早标准中,std::hash并没有默认支持std::variant,需要手动特化:

namespace std {
    template<>
    struct hash<std::variant<A,B>> {
        size_t operator()(const std::variant<A,B>& v) const {
            return std::visit([](const auto& val) {
                return std::hash<std::decay_t<decltype(val)>>{}(val);
            }, v);
        }
    };
}

如果你的编译器支持C++20及以上,std::hash已默认支持std::variant(前提是所有备选类型都有对应的std::hash特化,你这里已满足),这一步可省略。

完整修复后的代码

#include <variant>
#include <string>
#include <unordered_map>
#include <functional> // 用于std::visit

struct Base {
public:
    virtual std::size_t get_hash() const = 0;
};

struct A : public Base {
    std::string s;
public:
    A(std::string str): s{str} {}

    std::size_t get_hash() const override {
        return std::hash<std::string>{}(this->s);
    }

    bool operator==(const A& a) const {
        return a.s == this->s;
    }
};

struct B : public Base {
    int i;
public:
    B(int it): i{it} {}

    std::size_t get_hash() const override {
        return std::hash<int>{}(this->i);
    }

    bool operator==(const B& b) const {
        return b.i == this->i;
    }
};

namespace std {
    template<>
    struct hash<A> {
        size_t operator()(const A& a) const {
            return a.get_hash();
        }
    };

    template<>
    struct hash<B> {
        size_t operator()(const B& b) const {
            return b.get_hash();
        }
    };

    // C++17需要手动特化variant的hash,C++20可省略
    template<>
    struct hash<std::variant<A,B>> {
        size_t operator()(const std::variant<A,B>& v) const {
            return std::visit([](const auto& val) {
                return std::hash<std::decay_t<decltype(val)>>{}(val);
            }, v);
        }
    };
}

int main(int argc, char* argv[]) 
{
    std::unordered_map<std::variant<A,B>, int> map;

    std::variant<A,B> key1{A("hi")};
    std::variant<A,B> key2{B(1)};

    map.insert({key1, 1});
    map.insert({key2, 2});
}    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:45:41