【问题标题】:Why is operator!= synthesized from operator==, but not the other way around?为什么 operator!= 是从 operator== 合成的,而不是反过来呢?
【发布时间】:2020-08-25 14:39:14
【问题描述】:

在 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?
}

这似乎不一致,因为!=== 需要相反,如果一个可以从另一个合成,那么逆也应该起作用。这是什么原因?

【问题讨论】:

  • 这里 == 和 != 是两个完全不同的运算符。因此,除非您将它们定义为逆运算,否则它们的运算不是逆运算。
  • @OS2 - 除了它们在 C++20 下隐式反转。

标签: c++ language-lawyer c++20 comparison-operators


【解决方案1】:

因为这无益地增加了语言的复杂性。

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

没有理由在此处添加任意额外的灵活性。当你可以实现operator==时,你为什么实现operator!=


该语言目前在==<=> 之间具有很好的对称性,从理解规则和构建功能的角度来看,我认为这是有价值和重要的。虽然您可以x == y 定义为not (x != y) - 这对我来说似乎天生就很奇怪,因为“不等于”的名称是......而不是“等于”,但你可以这样做。但是你肯定不想用x < yx <= y 来定义x <=> y。那将是一个昂贵的转换,甚至无法正确确定比较类别。所以这样的方向会破坏我们所拥有的顺序的对称性,使语言规则更难理解。

【讨论】:

  • 好吧,我原以为一致性是一个好处。这会增加很多额外的复杂性吗?
  • @cigien 我并不认为这是一致性——我认为重要的一致性在==<=> 之间。
  • @cigien 具有所有程序的一致性,通过仅实现 == 而实现运算符而不是某些程序使用 != 实现它是一个好处。
  • @cigien 如果您将这样的类型传递给受equality_comparable 约束的函数模板,那么您就违反了该概念的语义约束,那就是库 UB。但它绝不是语言 UB,不。
  • @cigien 是的,格式正确。
猜你喜欢
  • 1970-01-01
  • 2014-08-30
  • 1970-01-01
  • 2018-07-30
  • 2020-08-28
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多