为什么operator!=从operator==合成,而不是反过来?

6
在c++20中,如果我为一个类型提供了一个operator==,那么编译器会合成一个operator!=,但反过来则不会。以下是一些代码
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?
}

这似乎是不一致的,因为必须要求!===是相反的,如果一个可以从另一个中合成,那么反过来也应该可以。这是什么原因?

这里的“==”和“!=”是两种完全不同的运算符。因此,除非你定义它们为相反数,它们的操作并不是相反的。 - user3091673
2
@OS2 - 除非在C++20下它们隐式地是反函数。 - StoryTeller - Unslander Monica
1个回答

10

因为这会增加语言的复杂性,但没有任何好处。

主要操作是相等性。C++20允许您只定义 operator== 来获得完整的相等操作(==!=)。同样,主要排序操作是 <=>,C++20 允许您只定义该操作并获得完整的排序运算符(<<=>>=)。

在这里添加任意的额外灵活性是没有道理的。为什么你只是要实现 operator!=,而不是 只是 实现 operator==


目前的语言在 ==<=> 之间具有良好的对称性,我认为这很有价值和重要,从理解规则和构建功能的角度来看。虽然你可以将 x == y 定义为 not (x != y),但那似乎本质上是奇怪的,因为“不相等”的名称不是“相等”,但你可以这样做。但你绝不能将 x <=> y 定义为 x < yx <= y。那将是一个昂贵的转换,甚至无法正确确定比较类别。这样做将破坏我们拥有的排序对称性,使语言规则更难理解。


嗯,我认为一致性是一个好处。这会增加很多额外的复杂性吗? - cigien
“!=”和“==”不是必须相反吗?我认为否则会出现未定义行为,因此这里需要一些一致性要求。 - cigien
4
所有程序都只使用 == 来实现运算符,而不是有些程序使用 != 实现它,这种一致性是有益的。 - eerorika
1
如果您将这样的类型传递到一个受限于“equality_comparable”的函数模板中,那么您就违反了该概念的语义约束,这将是库UB。但它从未是语言UB。 - Barry
1
@cigien 是的,这是格式良好的。 - Barry
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接