2017-11-15 9 views
13

operator<=>をC++ 20に追加すると、単純なメンバワイズ比較ではない場合にこの演算子を実装する方法を検討したいと考えました。オペレータ<=>をオプションで実装する

どのように私たちのどちらかがUTを比較したり基礎となる状態を比較、正しい戻り値の型を取得する必要がある場合である、optional<U>またはUoptional<T>を比較するための宇宙船演算子を実装するのでしょうか? latest paperにそのような例はありません。

+0

ところで、この機能は 'a >> operator <=>> c;'と互換性がありません。 –

+2

@ JohannesSchaub-litbはい、そうです。この提案でも言及されています。「トークン化は、いつものように最大の騒音に従います。 [...]これは唯一知られている後方ソースの非互換性であり、意図的です。 (私たち はスペースを使わずにそのようなコードを動作させるための特殊な解析ルールを採用することができましたが、私は が問題のためにあまりにも恩恵を受けているとは思いません)。とにかくそこにスペースやカッコがあるのを見て、私はここの提案に同意すると思います。 –

+0

@バリーそれは私が見ることができる限り、提案では言及されていません(以下の比較のみを提供しますが、後続の非互換性として以下のスイッチはありません。 –

答えて

6

これを実装する正しい方法は、std::compare_3way()関数テンプレートを使用して(1)そのような比較が実行可能かどうか、(2)比較カテゴリが実際にどのようなものかを処理することです。すべての比較演算子の実装は非常にコンパクトになり

template <typename T> 
class optional { 
public: 
    // ... 

    template <typename U> 
    constexpr auto operator<=>(optional<U> const& rhs) const 
     -> decltype(compare_3way(**this, *rhs)) 
    { 
     if (has_value() && rhs) { 
      return compare_3way(**this, *rhs); 
     } else { 
      return has_value() <=> rhs.has_value(); 
     } 
    } 

    template <typename U> 
    constexpr auto operator<=>(U const& rhs) const 
     -> decltype(compare_3way(**this, rhs)) 
    { 
     if (has_value()) { 
      return compare_3way(**this, rhs); 
     } else { 
      return strong_ordering::less; 
     } 
    } 

    constexpr strong_ordering operator<=>(nullopt_t) const { 
     return has_value() ? strong_ordering::greater 
          : strong_ordering::equal; 
    } 
}; 

他の4つの比較カテゴリに暗黙的に変換される3ウェイbool比較利回りstd::strong_ordering、。

同様に、strong_ordering::lessは、適宜、weak_ordering::lesspartial_ordering::lessstrong_equality::unequal、またはweak_equality::nonequivalentに暗黙的に変換されて。

+0

ここで '* lhs'と' * rhs'を呼び出していますそれらの1つが空であることを知っているとき。また、なぜ「オペレータ<=>」がメンバーとして実装されることを意図しているのであれば、これを非会員として実装していますか? –

+0

@DanielH 2番目の比較 – Yakk

+0

でタイポを修正しました( 'has_value'が' bool'への明示的キャストよりもはっきりしているように感じますが、それはスタイルの問題です)。 –

関連する問題