重写比较运算符会导致哪些重大更改? [英] What are the breaking changes caused by rewritten comparison operators?
问题描述
在C ++ 20中有一些关于重写比较运算符的新规则,我正在尝试了解它们的工作方式.我遇到了以下程序:
There are some new rules about rewritten comparison operators in C++20, and I'm trying to understand how they work. I've run into the following program:
struct B {};
struct A
{
bool operator==(B const&); // #1
};
bool operator==(B const&, A const&); // #2
int main()
{
B{} == A{}; // C++17: calls #2
// C++20: calls #1
}
实际上破坏了现有代码.我对此感到有些惊讶;#2
实际上对我来说仍然看起来更好:p
which actually breaks existing code. I'm a little surprised by this; #2
actually still looks better to me :p
那么这些新规则如何改变现有代码的含义?
So how do these new rules change the meaning of existing code?
推荐答案
该特定方面是一种简单的重写形式,即反转操作数.主要运算符 ==
和< =>
可以颠倒,辅助运算符!=
,<
,>
,< =
和> =
,可以根据原语进行重写.
That particular aspect is a simple form of rewriting, reversing the operands. The primary operators ==
and <=>
can be reversed, the secondaries !=
, <
, >
, <=
, and >=
, can be rewritten in terms of the primaries.
可通过一个相对简单的示例来说明倒车方面.
The reversing aspect can be illustrated with a relatively simple example.
如果没有特定的 B :: operator ==(A)
来处理 b == a
,则可以使用相反的方法来代替: A :: operator ==(B)
.这是有道理的,因为相等是双向关系:(b == a).
If you don't have a specific B::operator==(A)
to handle b == a
, you can use the reverse to do it instead: A::operator==(B)
. This makes sense because equality is a bi-directional relationship: (a == b) => (b == a)
.
次要运算符的重写涉及使用不同运算符.考虑 a>b
.如果找不到直接执行此功能的函数,例如 A :: operator>(B)
,则该语言将查找诸如 A :: operator&==((B)
,然后简单地从中计算结果.
Rewriting for secondary operators, on the other hand, involves using different operators. Consider a > b
. If you cannot locate a function to do that directly, such as A::operator>(B)
, the language will go looking for things like A::operator<=>(B)
then simply calculating the result from that.
这是一个简单的过程视图,但是我的大多数学生似乎都知道.如果需要更多详细信息,请参见C ++ 20的 [over.match.oper]
部分,这是重载分辨率的一部分( @
是操作符的占位符):
That's a simplistic view of the process but it's one that most of my students seem to understand. If you want more details, it's covered in the [over.match.oper]
section of C++20, part of overload resolution (@
is a placeholder for the operator):
对于关系和相等运算符,重写的候选包括运算符
< ==>
的所有成员,非成员和内置候选,其表达式为(x< => y)@ 0
使用该operator< =>
格式正确.
For the relational and equality operators, the rewritten candidates include all member, non-member, and built-in candidates for the operator
<=>
for which the rewritten expression(x <=> y) @ 0
is well-formed using thatoperator<=>
.
对于关系,相等和三向比较运算符,重写的候选还包括一个合成的候选,对于两个成员,非成员和内置候选,两个参数的顺序颠倒了.运算符< =>
,使用该 operator< =>格式的重写表达式
. 0 @(y< => x)
格式正确.
For the relational, equality, and three-way comparison operators, the rewritten candidates also include a synthesized candidate, with the order of the two parameters reversed, for each member, non-member, and built-in candidate for the
operator <=>
for which the rewritten expression 0 @ (y <=> x)
is well-formed using that operator<=>
.
因此不得不提供真正的 operator ==
和 operator<
然后进行电镀的日子已经过去了:
Hence gone are the days of having to provide a real operator==
and operator<
, then boiler-plating:
operator!= as ! operator==
operator> as ! (operator== || operator<)
operator<= as operator== || operator<
operator>= as ! operator<
如果我弄错了一个或多个错误,请不要抱怨,这只说明了我对C ++ 20更好的看法,因为您现在只需要提供最小的设置(很可能只是 operator< =>
以及您想要提高效率的任何其他功能),然后让编译器来照顾它:-)
Don't complain if I've gotten one or more of those wrong, that just illustrates my point on how much better C++20 is, since you now only have to provide a minimal set (most likely just operator<=>
plus whatever else you want for efficiency) and let the compiler look after it :-)
可以通过以下代码辨别为什么一个人比另一个人被选中的问题:
The question as to why one is being selected over the other can be discerned with this code:
#include <iostream>
struct B {};
struct A {
bool operator==(B const&) { std::cout << "1\n"; return true; }
};
bool operator==(B const&, A const&) { std::cout << "2\n"; return true; }
int main() {
auto b = B{}; auto a = A{};
b == a; // outputs: 1
(const B)b == a; // 1
b == (const A)a; // 2
(const B)b == (const A)a; // 2
}
那的输出表明是 a
的 const
-ness决定哪个是更好的候选者.
The output of that indicates that it's the const
-ness of a
deciding which is the better candidate.
顺便说一句,您可能想看看这篇文章,它提供了更深入的了解.
As an aside, you may want to have a look at this article, which offers a more in-depth look.
这篇关于重写比较运算符会导致哪些重大更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!