在C ++ 20中,关系运算符的工作方式发生了变化,特别是在引入了宇宙飞船<=>
运算符之后。特别是,如果仅提供operator==
,则将a != b
被重写为!(a == b)
。
来自[over.match.oper] /3.4:
重写的候选集确定如下:
- 对于关系([expr.rel])运算符,重写的候选对象包括表达式x <=> y的所有未重写的候选对象。
- 对于关系([expr.rel])和三向比较([expr.spaceship])运算符,重写的候选还包括一个合成的候选,两个参数的顺序颠倒了,对于每个未重写的候选表达式y <=> x。
- 对于!=运算符([expr.eq]),重写的候选对象包括表达式x == y的所有未重写的候选对象。
- 对于相等运算符,对于表达式y == x的每个未重写候选,重写的候选还包括两个参数的顺序相反的合成候选。
- 对于所有其他运算符,重写的候选集为空。
和[over.match.oper] / 9:
如果通过重载决议为操作符@选择了重写的operator ==候选对象,则其返回类型应为cv bool,并且x @ y解释为:
- 如果@是!=并且选择的候选对象是参数相反顺序的合成候选对象!(y == x),
- 否则,如果@是!=,!(x == y),
- 否则(当@是==时),y == x,
在每种情况下,都使用选定的重写运算符==候选。
因此,operator!=
不再需要显式的重载。删除运算符并没有更改比较语义。
operator!=
据我所知,所有容器都已被移除(例如检查矢量概要)。唯一的例外是容器适配器std::queue
和std::stack
:我的猜测是,如果与相等的容器不对称,则当与第三方容器一起使用时,它将保留向后兼容性。