对于许多标准库类型,为什么在C ++ 20中删除了operator!=?

问题描述 投票:37回答:2

根据cppreferencestd::type_info::operator!=被C ++ 20删除,但是std::type_info::operator==显然仍然存在。

背后的原因是什么?我可能会同意比较不平等是没有意义的,但是然后比较相等也同样是没有意义的,不是吗?

同样,许多其他标准库类型的operator!=,包括std::unordered_map::operator!=std::unordered_map::operator!=之类的容器,将根据cppreference在C ++ 20中删除。

相比std::unordered_set::operator!=,必须写std::unordered_set::operator!=不会使任何代码更清晰,相反,相反...

c++ c++-standard-library comparison-operators c++20 equality-operator
2个回答
37
投票

我们不再需要if(!(id1 == id2))提供的库。提供if(id1 != id2)可使编译器自己进行一些工作并根据operator!=评估operator==

[over.match.oper]

a != b对于一元运算符@,其操作数的类型为cv非限定版本为T1,对于二进制运算符@,左简历不合格版本为T1且类型为右的类型的操作数cv不合格版本为T2的类型的操作数,四组候选人职能,指定成员候选人,非成员候选人,内置候选人和改写的候选人是构造如下:

a == b对于!=运算符([expr.eq]),重写的候选包括表达式x == y的所有未重写候选。

[3和许多其他库类型已将其3.4.3删除为std::type_info的一部分。


57
投票

在C ++ 20中,关系运算符的工作方式发生了变化,特别是通过引入太空飞船operator!=运算符。特别是,如果仅提供P1614 - The Mothership has Landed,则<=>将被重写为operator==

来自a != b

重写的候选集确定如下:

  • 对于关系([expr.rel])运算符,重写的候选包括表达式x <=> y的所有未重写的候选。
  • 对于关系([expr.rel])和三向比较([expr.spaceship])运算符,对于每个未重写的候选者,重写的候选者还包括一个合成的候选者,两个参数的顺序相反对于表达式y <=> x。
  • 对于!=运算符([expr.eq]),重写的候选包括表达式x == y的所有未重写的候选。
  • 对于相等运算符,对于表达式y == x的每个未重写候选,重写的候选还包括两个参数的顺序相反的合成候选。
  • 对于所有其他运算符,重写的候选集为空。

!(a == b)

如果通过重载决议为运算符@选择了重写的运算符==候选,其返回类型应为cv bool,并且x @ y解释为:

  • 如果@是!=,并且所选候选是参数相反顺序的合成候选,!(y == x),
  • 否则,如果@是!=,!(x == y)
  • 否则(当@是==时,y ​​== x,

在每种情况下都使用选择的重写运算符==候选。

因此,不再需要[over.match.oper]/3.4的显式重载。删除运算符并未更改比较语义。

据我所知,所有容器均已删除其[over.match.oper]/9(例如,检查operator!=)。唯一的例外是容器适配器operator!=the vector synopsis:我的猜测是,如果与相等的容器不对称,则当与第三方容器一起使用时,它将保留向后兼容性。

© www.soinside.com 2019 - 2024. All rights reserved.