哪些运算符隐式定义/生成 C++ 中的其他运算符?
Which operators implictly define / generate other operators in C++?
我知道在 C++ 中定义某些运算符可以让编译器为 class 生成其他运算符。从我读到的 in this cppreference article 来看,似乎以下内容成立:
operator==
必须明确定义(可能是默认值)才能使用。
operator!=
是从 operator==
生成的,如果它没有明确定义并且 operator==
被定义。
operator<=>
生成其他四个关系运算符(如果一切按计划进行,即 operator<=>
returns 可以由其他四个解释的结果,并且对两者都有很好的定义原始和反向参数顺序)
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
- 比较运算符是对称的很重要。
我知道在 C++ 中定义某些运算符可以让编译器为 class 生成其他运算符。从我读到的 in this cppreference article 来看,似乎以下内容成立:
operator==
必须明确定义(可能是默认值)才能使用。operator!=
是从operator==
生成的,如果它没有明确定义并且operator==
被定义。operator<=>
生成其他四个关系运算符(如果一切按计划进行,即operator<=>
returns 可以由其他四个解释的结果,并且对两者都有很好的定义原始和反向参数顺序)operator<=>
不会生成operator==
即使它 returnsstd::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
- 比较运算符是对称的很重要。