web-dev-qa-db-ja.com

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

cppreference によると、C++ 20では_std::type_info::operator!=_が削除されますが、_std::type_info::operator==_は残っているようです。

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

同様に、 _operator!=__std::unordered_map::operator!=_ などのコンテナを含む、他の多くの標準ライブラリタイプの_std::unordered_set::operator!=_は、C++では削除されますcppreferenceに従って20。

if(!(id1 == id2))と書かなければならないということは、if(id1 != id2)に比べてコードが明確になるわけではなく、対照的に...

43
Aconcagua

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

From [[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::queue_および_std::stack_です。等価演算子が対称でない場合に備えて、サードパーティのコンテナーで使用する場合、下位互換性を維持するためだと思います。

61
N. Shead

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_infoおよびその他の多くのライブラリタイプでは、operator!=P1614-母艦の着陸 の一部として削除されました。