在 C++20 中,关系运算符的工作方式发生了变化,特别是引入了 spaceship<=>
运算符。特别是,如果您只提供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!=
不再需要显式重载 for。删除运算符并没有改变比较语义。
据我所知,所有容器都已operator!=
被移除(例如检查向量概要)。唯一的例外是容器适配器std::queue
和std::stack
:我的猜测是,它是为了在与第三方容器一起使用时保持向后兼容性,以防相等运算符不对称。