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

通过太空船运算符让编译器自动生成==、<、>等比较运算符的问题

解决C++太空船运算符无法自动生成跨类型operator==的问题

问题原因

C++20的太空船运算符(<=>)仅会在同类比较场景下自动生成对应的operator==:即当你为类定义了与自身类型的operator<=>(无论是= default还是自定义实现),编译器才会自动推导生成同类的相等性运算符。而你定义的是JSON与double、std::string的跨类型operator<=>,这类场景下编译器不会自动生成对应的operator==,这就是编译报错的核心原因。

解决方案

根据你希望保留“类型不匹配时std::get抛出异常”的需求,提供两种可行方案:

方案1:手动实现跨类型operator==

直接为JSON类补充与double、std::string的相等性判断重载,和已有的<=>配对:

#include <compare>
#include <iostream>
#include <variant>
#include <string>

class JSON : public std::variant<std::monostate, double, std::string> {
public:
    using variant::variant;

    auto operator<=>(std::string str) const {
        return std::get<std::string>(*this) <=> str;
    }
    auto operator<=>(double d) const {
        return std::get<double>(*this) <=> d;
    }

    // 补充对应的相等性运算符
    bool operator==(std::string str) const {
        return std::get<std::string>(*this) == str;
    }
    bool operator==(double d) const {
        return std::get<double>(*this) == d;
    }
};
  
int main()
{
    JSON myjson = 2.3;

    if (myjson == 2.3) {
        std::cout << "JSON was 2.3" << std::endl;
    }
}

该方案完全保留你原本的逻辑:当JSON存储的类型与比较参数不匹配时,std::get会抛出std::bad_variant_access异常。

方案2:复用std::variant的默认比较逻辑

如果你希望避免直接调用std::get,可以将double/std::string转换为JSON对象,复用std::variant自带的比较运算符:

#include <compare>
#include <iostream>
#include <variant>
#include <string>

class JSON : public std::variant<std::monostate, double, std::string> {
public:
    using variant::variant;
    // 继承std::variant的默认比较运算符
    using variant::operator<=>>;
    using variant::operator==;

    // 跨类型比较重载,转换为同类后复用默认逻辑
    auto operator<=>(double d) const {
        return *this <=> JSON{d};
    }
    auto operator<=>(std::string str) const {
        return *this <=> JSON{str};
    }

    bool operator==(double d) const {
        return *this == JSON{d};
    }
    bool operator==(std::string str) const {
        return *this == JSON{str};
    }
};
  
int main()
{
    JSON myjson = 2.3;

    if (myjson == 2.3) {
        std::cout << "JSON was 2.3" << std::endl;
    }
}

注意:该方案中,当JSON存储的类型与比较参数不匹配时,会直接返回false而非抛出异常。如果需要异常逻辑,仍建议使用方案1。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:05:56