多くの標準ライブラリタイプのC ++ 20でoperator!=が削除されるのはなぜですか?


44

cppreferenceによると、std::type_info::operator!=C ++ 20で削除されますが、std::type_info::operator==明らかに残っています。

背後にある理由は何ですか?不平等を比較することは無意味であることに同意するかもしれませんが、平等を比較することも同様に無意味ですよね?

同様に、operator!=などの容器を含む他の多くの標準ライブラリの種類のstd::unordered_map::operator!=std::unordered_set::operator!=cppreferenceに従って20 C ++で除去されます。

書き込みに持つことif(!(id1 == id2))に比べて任意のコードがどの明確にしないif(id1 != id2)だけで、反対、対照的に、...

回答:


62

C ++ 20では、特に宇宙船<=>演算子の導入により、関係演算子の動作方法が変更されました。特に、のみを指定したoperator==場合、a != bはに書き換えられ!(a == b)ます。

[over.match.oper] /3.4

書き換えられた候補セットは、次のように決定されます。

  • 関係演算子([expr.rel])の場合、書き換えられた候補には、式x <=> yの書き換えられていないすべての候補が含まれます。
  • 関係演算子([expr.rel])および3者間比較([expr.spaceship])演算子の場合、書き換えられた候補には、2つのパラメーターの順序が逆になった合成候補も含まれます。式y <=> x。
  • !=演算子([expr.eq])の場合、書き換えられた候補には、式x == yの書き換えられていないすべての候補が含まれます。
  • 等式演算子の場合、書き換えられた候補には、式y == xの書き換えられていない各候補について、2つのパラメーターの順序が逆になった合成候補も含まれます。
  • 他のすべての演算子の場合、書き換えられた候補セットは空です。

そして[over.match.oper] / 9

書き換えられたoperator ==候補が演算子@のオーバーロード解決によって選択された場合、その戻り値の型はcv boolであり、x @ yは次のように解釈されます。

  • @が!=で、選択した候補がパラメーターの順序が逆の合成候補である場合、!(y == x)、
  • それ以外の場合、@が!= 、!(x == y)の場合、
  • それ以外の場合(@が==の場合)、y == x、

いずれの場合も、選択した書き換え済みの演算子==候補を使用します。

そのため、の明示的なオーバーロードoperator!=は不要になりました。演算子を削除しても、比較セマンティクスは変わりません。

operator!=私の知る限り、すべてのコンテナは削除されています(たとえば、ベクトルの概要を確認してください)。唯一の例外は、コンテナアダプタですstd::queuestd::stack:私の推測では、それが等価演算子が対称でない場合には、サードパーティ製のコンテナで使用する場合の後方互換性を維持することであるということです。


7
p1614も興味深いかもしれません。私はそれが過負荷を取り除く提案だったと信じています。
N. Shead

39

ライブラリを提供する必要はoperator!=もうありません。提供するoperator==ことで、コンパイラーはジャグリングを実行し、すべてを単独a != bで評価しa == bます。

[over.match.oper]

3 cv非修飾バージョンがT1である型のオペランドを持つ単項演算子@の場合、およびcv非修飾バージョンがT1である型の左オペランドとcv-非修飾型の右オペランドを持つ二項演算子@の場合非修飾バージョンはT2であり、指定されたメンバー候補、非メンバー候補、組み込み候補、および書き換えられた候補の4つの候補関数のセットは、次のように構成されます。

3.4.3!=演算子([expr.eq])の場合、書き換えられた候補には、式x == yの書き換えられていないすべての候補が含まれます。

std::type_infoP1614のoperator!=一部として、さらに多くのライブラリタイプが削除されました-母船が上陸しました

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.