为什么 operator!= 是由 operator== 合成的,而不是反过来呢?
Why is operator!= synthesized from operator==, but not the other way around?
在 c++20 中,如果我为类型提供 operator==
,则编译器会合成一个 operator!=
,但反之则不然。
这是一些 code:
struct A {};
bool operator==(A const&, A const&);
struct B {};
bool operator!=(B const&, B const&);
int main()
{
if (A{} != A{}) {} // error in c++17
// ok in c++20
if (B{} == B{}) {} // error in c++17
// error in c++20, why?
}
这似乎不一致,因为!=
和==
需要相反,如果一个可以从另一个合成,那么逆应该也可以。这是什么原因?
因为这无益于增加了语言的复杂性。
主要操作是相等。 C++20 让您只需定义 operator==
即可获得完整的等式运算(==
和 !=
)。同样,主要的排序运算符是 <=>
,C++20 允许您只定义它并获得排序运算符的完整补充(<
、<=
、>
和>=
).
没有理由在此处添加任意额外的灵活性。当你可以只是实施operator==
时,你为什么只是实施operator!=
?
该语言目前在 ==
和 <=>
之间有很好的对称性,我认为从理解规则和构建功能的角度来看,这是有价值和重要的。虽然你 可以 将 x == y
定义为 not (x != y)
- 这对我来说似乎很奇怪,因为“不等于”的名称是......不是“等于”,但你可以这样做。但是您绝对不想根据 x < y
或 x <= y
来定义 x <=> y
。那将是一个代价高昂的转换,甚至无法正确确定比较类别。所以这样的方向会打破我们现有的顺序的对称性,使语言规则更难理解。
在 c++20 中,如果我为类型提供 operator==
,则编译器会合成一个 operator!=
,但反之则不然。
这是一些 code:
struct A {};
bool operator==(A const&, A const&);
struct B {};
bool operator!=(B const&, B const&);
int main()
{
if (A{} != A{}) {} // error in c++17
// ok in c++20
if (B{} == B{}) {} // error in c++17
// error in c++20, why?
}
这似乎不一致,因为!=
和==
需要相反,如果一个可以从另一个合成,那么逆应该也可以。这是什么原因?
因为这无益于增加了语言的复杂性。
主要操作是相等。 C++20 让您只需定义 operator==
即可获得完整的等式运算(==
和 !=
)。同样,主要的排序运算符是 <=>
,C++20 允许您只定义它并获得排序运算符的完整补充(<
、<=
、>
和>=
).
没有理由在此处添加任意额外的灵活性。当你可以只是实施operator==
时,你为什么只是实施operator!=
?
该语言目前在 ==
和 <=>
之间有很好的对称性,我认为从理解规则和构建功能的角度来看,这是有价值和重要的。虽然你 可以 将 x == y
定义为 not (x != y)
- 这对我来说似乎很奇怪,因为“不等于”的名称是......不是“等于”,但你可以这样做。但是您绝对不想根据 x < y
或 x <= y
来定义 x <=> y
。那将是一个代价高昂的转换,甚至无法正确确定比较类别。所以这样的方向会打破我们现有的顺序的对称性,使语言规则更难理解。