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

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

我知道在 C++ 中定义某些运算符可以让编译器为类生成其他运算符。从我读到的在这篇 cppreference 文章中看来以下内容是正确的:

  1. operator==
    必须明确定义(可能是默认值)才能使用。
  2. 如果未显式定义且定义了
  3. operator!=
    ,则 
    operator==
    是从
    operator==
    生成的。
  4. operator<=>
    生成其他四个关系运算符(如果一切按计划进行,即
    operator<=>
    返回其他四个可以解释的结果,并且对于原始参数顺序和反向参数顺序都有明确定义)
  5. 即使它返回
  6. operator<=>
    operator==
    也不会生成
    std::strong_ordering
    ,据我所知,当且仅当两个比较对象相同(无法区分)时,应该返回一个与
    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);
}

返回错误

no match for ‘operator==’ (operand types are ‘Foo’ and ‘Foo’)

我想知道的是,首先,为什么

operator<=>
不生成
operator==
,其次 - 是否存在哪些运算符生成其他运算符(以及哪些运算符)的完整列表,或者 cppreference 文章是否完整在这方面并且没有产生其他运营商?例如,我期望
operator+(Foo)
operator-()
生成
operator-(Foo)
,因为减法只不过是加上加法逆元。然而,事实证明这是不正确的,我也测试过。

c++ operator-overloading c++20
1个回答
1
投票

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

只有一种情况是一个运算符定义/生成另一个运算符,即当您default

operator<=>
时,您also获得默认的
operator==
。这是完整的列表。

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

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

在您的情况下,

f == g
根本没有
operator==
候选者,所以它的格式不正确。
<=>
的原始设计也会尝试将此表达式重写为
(f <=> g) == 0
(同样,不是生成
operator==
而是重写表达式)。但这被证明存在严重的性能问题,因此它被更改为不这样做。您可以在我的博客上阅读有关 C++20 中的比较的更多信息。

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

bool operator==(Foo const&) const = default;
或者如果您愿意的话可以手动编写。不管怎样,你的 

operator<=>

 缺少 
const
 - 比较运算符对称很重要。

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