哪些运算符隐式定义/生成 C++ 中的其他运算符?

Which operators implictly define / generate other operators in C++?

我知道在 C++ 中定义某些运算符可以让编译器为 class 生成其他运算符。从我读到的 in this cppreference article 来看,似乎以下内容成立:

  1. operator== 必须明确定义(可能是默认值)才能使用。
  2. operator!= 是从 operator== 生成的,如果它没有明确定义并且 operator== 被定义。
  3. operator<=> 生成其他四个关系运算符(如果一切按计划进行,即 operator<=> returns 可以由其他四个解释的结果,并且对两者都有很好的定义原始和反向参数顺序)
  4. operator<=> 不会生成 operator== 即使它 returns std::strong_ordering 据我所知,应该 return 一个对象相当于0 当且仅当两个比较对象相同(无法区分)。我用下面的代码自己测试了这个
#include <iostream>

class Foo
{
public:
    int x;
    int y;

    // Lexicographic ordering but by the y member first, and by x second.
    std::strong_ordering operator<=>(const Foo& other)
    {
        if (std::strong_ordering cmp = y <=> other.y; cmp != 0)
            return cmp;
        return x <=> other.x;
    }
};

int main()
{
    Foo f = {1, 1}, g = {1, 0};
    std::cout << (f == g);
}

其中 return 错误 no match for ‘operator==’ (operand types are ‘Foo’ and ‘Foo’)

我想知道的是,首先,为什么 operator<=> 不生成 operator==,其次 - 是否有一个完整的列表,其中列出了哪些运算符生成其他运算符(以及哪些运算符),或者那篇 cppreference 文章在这方面是否完整并且没有生成其他运算符?例如,我希望 operator+(Foo)operator-() 生成 operator-(Foo),因为减法只不过是加法逆运算。然而,事实证明这是不正确的,我也进行了测试。

Which operators implicitly define / generate other operators in C++?

只有一种情况是一个运算符 defines/generates 另一个运算符,那就是当你 default operator<=>also 得到默认的 operator==。这是完整的列表。

其他一切都不基于声明运算符,而是基于重写表达式:

  • 并不是 operator!= 是从 operator== 生成的,而是表达式 x != y 也试图计算为 !(x == y)
  • 并不是 operator< 是从 operator<=> 生成的,而是表达式 x < y 也试图计算为 (x <=> y) < 0

在您的例子中,f == g 根本没有 operator== 候选项,因此它的格式不正确。 <=> 的原始设计也会尝试将此表达式重写为 (f <=> g) == 0(同样,不是生成 operator== 而是重写表达式)。但这显示有 serious performance issues and so it was changed to not do this. You can read more about Comparisons in C++20 here.

在这种情况下,由于您正在进行成员比较,您可以简单地:

bool operator==(Foo const&) const = default;

如果您愿意,也可以手动编写。无论哪种方式,您的 operator<=> 都缺少一个 const - 比较运算符是对称的很重要。