让编译器通过 spaceship-operator 编写操作符==、<, >等

问题描述 投票:0回答:1

我正在向宇宙飞船操作员碰碰运气。假设我有一个类似变体的对象(我可以方便地从具有固定模板参数的

std::variant
派生),并且我想定义运算符 ==、<, >、!= 等...为了便于比较,我想我可以只是宇宙飞船-它根据包含的类型并让编译器自己定义所有运算符:

演示

#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;
    }
};
  
int main()
{
    JSON myjson = 2.3;

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

然而这个方法的结果是:

<source>: In function 'int main()':
<source>:22:16: error: no match for 'operator==' (operand types are 'JSON' and 'double')
   22 |     if (myjson == 2.3) {
      |         ~~~~~~ ^~ ~~~
      |         |         |
      |         JSON      double

我本以为编译器现在知道如何为我的变体对象编写

operator==
,以防 rhs 是双精度值或 rhs 是字符串。如果变体包含不同的替代方案,我可以接受 std::get 扔给我。

c++ comparison std-variant spaceship-operator
1个回答
0
投票

来自 默认比较 (C++20 起):

如果operator<=>是默认的并且operator==根本没有声明, 那么operator==是隐式默认的。

正如您在上面的链接中看到的,这是基于

operator==
的隐式默认值
operator<=>
的唯一提及。

在您的情况下,

operator<=>
不是
default
ed,因此上述内容不适用。
因此,您需要提供
operator==
(或拥有它本身
default
ed)。

© www.soinside.com 2019 - 2024. All rights reserved.