1. ホーム
  2. c++

[解決済み】C++の<=>(「スペースシップ」、三者間比較)演算子とは何ですか?

2022-04-16 02:18:16

質問

について学ぼうとしているうちに C++ 演算子で、奇妙な比較演算子を発見しました。 cppreference.com , * というようなテーブルを作成しました。

C++でよく使われる演算子なら、勉強しておこうかな、と。しかし、この謎を解明しようとする試みは、すべて失敗に終わった。ここ、Stack Overflowでさえ、私は検索でヒットしなかったのです。

とは関係があるのでしょうか? <=> C++ ?

また、あるとすれば、この演算子は具体的に何をするのでしょうか?

<サブ * この間、cppreference.com はこのページを更新し、現在では、このページには <=> 演算子を使用します。

どのように解決するのですか?

について 2017-11-11 は、ISO C++委員会が採択した ハーブ・サッター の提案は <=> "宇宙船" 三項比較演算子 に追加された新機能の1つである C++20 . というタイトルの論文で 一貫性のある比較 Sutter、Maurer、Brownの3人は、新しいデザインのコンセプトを実証しています。提案の概要については、以下、論文からの抜粋をご覧ください。

表現方法 a <=> b を比較するオブジェクトを返します。 <0 もし a < b を比較します。 >0 もし a > b と比較し ==0 aとbが が等しい/等価である。

よくあるケース 型に対するすべての比較を書きたい場合 X というタイプで Y と書くだけで、メンバーワイズセマンティクスを使用することができます。

auto X::operator<=>(const Y&) =default;

高度な事例 型に対するすべての比較を書きたい場合 X というタイプで Y と書くだけです。 演算子<=> を取る。 Y を使用することができます。 =default を返し、必要であればメンバーごとのセマンティクスを取得します。 というカテゴリがあります。

  • を返します。 オーダー を自然にサポートしている場合、その型は < を効率よく生成し、対称的な < , > , <= , >= , そして != を返し、それ以外の場合は _equality を効率的に生成し 対称的な == != .
  • 戻る strong_ もしあなたの型が a == b を意味します。 f(a) == f(b) (置換性、ここで f が比較優位な状態のみを読み取る。 を使用してアクセスできます。 const メンバ)、それ以外の場合は 弱い .

比較対象カテゴリー

5つの比較カテゴリが定義されています。 std:: の型があり、それぞれ以下の定義済みの値を持つ。

+--------------------------------------------------------------------+
|                  |          Numeric  values          | Non-numeric |
|     Category     +-----------------------------------+             |
|                  | -1   | 0          | +1            |   values    |
+------------------+------+------------+---------------+-------------+
| strong_ordering  | less | equal      | greater       |             |
| weak_ordering    | less | equivalent | greater       |             |
| partial_ordering | less | equivalent | greater       | unordered   |
| strong_equality  |      | equal      | nonequal      |             |
| weak_equality    |      | equivalent | nonequivalent |             |
+------------------+------+------------+---------------+-------------+

これらの型間の暗黙の変換は,以下のように定義されている。

  • strong_ordering を値{で指定します。 less , equal , greater } に暗黙のうちに変換される。
    • weak_ordering という値を持つ { less , equivalent , greater }
    • partial_ordering を値{で指定します。 less , equivalent , greater }
    • strong_equality を値{で指定します。 unequal , equal , unequal }
    • weak_equality を値{で指定します。 nonequivalent , equivalent , nonequivalent }
  • weak_ordering を値{で指定します。 less , equivalent , greater } に暗黙のうちに変換される。
    • partial_ordering という値を持つ { less , equivalent , greater }
    • weak_equality を値{で指定します。 nonequivalent , equivalent , nonequivalent }
  • partial_ordering を値{で指定します。 less , equivalent , greater , unordered } に暗黙のうちに変換される。
    • weak_equality という値を持つ { nonequivalent , equivalent , nonequivalent , nonequivalent }
  • strong_equality を値{で指定します。 equal , unequal } に暗黙のうちに変換される。
    • weak_equality という値を持つ { equivalent , nonequivalent }

三者間比較

<=> というトークンが紹介されています。文字列 <=> にトークン化されます。 <= > は、古いソースコードでは 例えば X<&Y::operator<=> は、その意味を保つためにスペースを追加する必要があります。

オーバーロード可能な演算子 <=> は三者間比較関数で、優先順位は < よりも低く、かつ << . と比較できる型を返します。 0 しかし、式テンプレートのサポートなど、他の戻り値も許容される。すべて <=> 言語および標準ライブラリで定義されている演算子は、前述の5つのうち1つを返します。 std:: 比較カテゴリタイプ

言語タイプについては、以下の組み込み <=> 同じ型の比較は提供される。全ては constexpr ただし、特に断りがある場合を除く。これらの比較は、スカラー昇格/変換を使用して異種混合で呼び出すことはできません。

  • 対象 bool 型、integral 型、pointer 型があります。 <=> を返します。 strong_ordering .
  • ポインタ型については,異なる cv-qualification や派生型から基底型への変換が,同種の組み込みを呼び出すことを許可しています. <=> があり、ビルトインのヘテロジニアス operator<=>(T*, nullptr_t) . 同じオブジェクト/アロケーションへのポインタの比較のみが定数式となります。
  • 基本的な浮動小数点型の場合。 <=> は以下を返します。 partial_ordering また、引数をより大きな浮動小数点型に広げることで、異種混在で呼び出すことができます。
  • 列挙の場合。 <=> は、列挙型の基礎となる型の <=> .
  • について nullptr_t , <=> リターン strong_ordering となり、常に equal .
  • コピー可能な配列の場合。 T[N] <=> T[N] と同じ型を返します。 T 's <=> で、辞書的な要素ごとの比較を行います。このとき <=> は他の配列に適用されます。
  • について void はありません。 <=> .

<サブ この演算子の内部構造をよりよく理解するために、オリジナルの 論文 . これはあくまで検索エンジンを使って調べたことです。