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

Why is operator!= removed in C++20 for many standard library types?

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

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

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

if(id1 != id2)相比,必须编写if(!(id1 == id2))并不能使任何代码更清晰,相反,恰恰相反...

我们不再需要 operator!= 提供的库。提供 operator== 允许编译器根据 a == b 自行进行一些杂耍和评估 a != b

[over.match.oper]

3 For a unary operator @ with an operand of a type whose cv-unqualified version is T1, and for a binary operator @ with a left operand of a type whose cv-unqualified version is T1 and a right operand of a type whose cv-unqualified version is T2, four sets of candidate functions, designated member candidates, non-member candidates, built-in candidates, and rewritten candidates, are constructed as follows:

3.4.3 For the != operator ([expr.eq]), the rewritten candidates include all non-rewritten candidates for the expression x == y.

std::type_info 和更多库类型的 operator!= 作为 P1614 - The Mothership has Landed.

的一部分被删除

在 C++20 中,关系运算符的工作方式发生了变化,特别是引入了宇宙飞船 <=> 运算符。特别是,如果您只提供 operator==,那么 a != b 将被重写为 !(a == b)

来自 [over.match.oper]/3.4:

The rewritten candidate set is determined as follows:

  • For the relational ([expr.rel]) operators, the rewritten candidates include all non-rewritten candidates for the expression x <=> y.
  • For the relational ([expr.rel]) and three-way comparison ([expr.spaceship]) operators, the rewritten candidates also include a synthesized candidate, with the order of the two parameters reversed, for each non-rewritten candidate for the expression y <=> x.
  • For the != operator ([expr.eq]), the rewritten candidates include all non-rewritten candidates for the expression x == y.
  • For the equality operators, the rewritten candidates also include a synthesized candidate, with the order of the two parameters reversed, for each non-rewritten candidate for the expression y == x.
  • For all other operators, the rewritten candidate set is empty.

[over.match.oper]/9

If a rewritten operator== candidate is selected by overload resolution for an operator @, its return type shall be cv bool, and x @ y is interpreted as:

  • if @ is != and the selected candidate is a synthesized candidate with reversed order of parameters, !(y == x),
  • otherwise, if @ is !=, !(x == y),
  • otherwise (when @ is ==), y == x,

in each case using the selected rewritten operator== candidate.

因此,不再需要 operator!= 的显式重载。删除运算符并没有改变比较语义。

据我所知,所有容器的 operator!= 都被移除了(检查例如 the vector synopsis)。唯一的例外是容器适配器 std::queuestd::stack:我猜这是为了在与第三方容器一起使用时保持向后兼容性,以防相等运算符不对称。