【问题标题】:Which operators implictly define / generate other operators in C++?哪些运算符隐含地定义/生成 C++ 中的其他运算符?
【发布时间】:2021-12-23 20:34:14
【问题描述】:

我知道在 C++ 中定义某些运算符可以让编译器为一个类生成其他运算符。从我读到的in this cppreference article 看来,以下情况似乎是正确的:

  1. operator== 必须明确定义(可能是默认值)才能使用。
  2. operator!= 是从 operator== 生成的,如果它没有明确定义并且 operator== 已经定义。
  3. operator<=> 生成其他四个关系运算符(如果一切按计划进行,即operator<=> 返回一个可能被其他四个解释的结果,并且对于原始参数顺序和反向参数顺序都有很好的定义)
  4. 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&lt;=&gt; 不生成 operator==,其次 - 是否有完整列表列出哪些运算符生成其他运算符(以及哪些运算符),或者是 cppreference文章在这方面是否完整并且没有其他运算符正在生成?例如,我希望operator+(Foo)operator-() 生成operator-(Foo),因为减法只不过是加法逆运算。然而,事实证明这是不真实的,我也对此进行了测试。

【问题讨论】:

标签: c++ operator-overloading c++20


【解决方案1】:

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

只有一种情况是一个运算符定义/生成另一个运算符,那就是当你默认 operator&lt;=&gt;得到一个默认的operator==。这是完整的列表。

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

  • 不是operator!= 是从operator== 生成的,而是表达式x != y 也试图评估为!(x == y)
  • 不是operator&lt; 是从operator&lt;=&gt; 生成的,而是表达式x &lt; y 也试图评估为(x &lt;=&gt; y) &lt; 0

在您的情况下,f == g 根本没有 operator== 候选人,所以它的格式不正确。 &lt;=&gt; 的原始设计也会尝试将此表达式重写为(f &lt;=&gt; g) == 0(同样,不生成operator==,而是重写表达式)。但是这显示有serious performance issues,所以它是changed to not do this。您可以阅读更多关于 C++20 中的比较here

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

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

如果您愿意,也可以手动编写。无论哪种方式,您的operator&lt;=&gt; 都缺少const - 比较运算符必须是对称的。

【讨论】:

  • 感谢您了解operator!= 和四个比较运算符实际发生的情况。也感谢您链接的有关性能的来源。最后,很高兴您注意到我缺少 const,尽管这是草率测试的结果。
猜你喜欢
  • 1970-01-01
  • 2017-02-27
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
相关资源
最近更新 更多