テンプレートパラメータがそれを提供する場合、条件付きで比較演算子のオーバーロードを提供します

ConditionalMethod

テンプレート化されたクラスがあります

template <typename T>
class SometimesComparable
{
public:
  T x1;
  T x2;
  // Other functionally provided unconditionally
  // ...
  // To be provided only if T provides operator<
  // bool operator<(SometimesComparable const & other) const 
  // {
  //   return x1 < other.x1 && x2 < other.x2;
  // }
};

bool operator<()テンプレートパラメータも提供する場合にのみ提供する必要がありますbool operator<()

SFINAEを使用した同様の質問/回答を読みましたが、このケースにアイデアを適応させることができなかったため、理解できなかったことがあるはずです。

それらの答えを真似て私はクラスを持っています

template <typename T>
class HasLessThan
{
private:
    typedef char YesType[1];
    typedef char NoType[2];

    template <typename C> static YesType& test( decltype(&C::operator<)     );
    template <typename C> static NoType& test(...);

public:
    enum { value = sizeof(test<T>(0)) == sizeof(YesType) };
};

testそのメンバーを介してそのメソッド使用してvalue、クラスがT提供するかどうかを検出しますoperator<

SometimesComparable私が定義しているクラスの中で

typename std::enable_if<HasLessThan<T>::value, bool>::type
operator<(ConditionalMethodProvided &other)
{
    return x1 < other.x1 && x2 < other.x2;
}

次に、テスト用に、機能する用途のために、クラスがあります

class TypeWithLessThan
{
public:
  int x;
  TypeWithLessThan(int x) : x(x) {};
  bool operator<(TypeWithLessThan &other) {return x < other.x;};
};

int main(int argc, char *argv[])
{
    ConditionalMethodProvided C(TypeWithLessThan(2), TypeWithLessThan(3));
    ConditionalMethodProvided D(TypeWithLessThan(5), TypeWithLessThan(7));
    std::cout << (C < D) << std::endl;

    return 0;
}

質問部分:これは問題ありません。さて、私が見逃しているのは、そのような実装はどうあるべきかということです

int main(int argc, char *argv[])
{
    ConditionalMethodProvided C(2, 3);
    ConditionalMethodProvided D(5, 7);
    std::cout << (C < D) << std::endl;

    return 0;
}

また、正常にコンパイルされます。

SometimesComparable友達メソッドに追加しみまし

friend
typename std::enable_if<HasLessThan<T>::value, bool>::type
operator<(ConditionalMethodProvided & a1, ConditionalMethodProvided &a2)
{
    return a1.x1 < a2.x1 && a1.x2 < a2.x2;
};

最初のものoperator<と友人のものの両方があると、あいまいなオーバーロードが作成さConditionalMethodProvided<int, int>れます。それがないと、の比較がコンパイルされません。

私は両方intTypeWithLessThan働きたいです。


編集:

単一のブロック内のコード。

#include <iostream>
#include <type_traits>

template <typename T>
class HasLessThan
{
private:
    typedef char YesType[1];
    typedef char NoType[2];

    template <typename C> static YesType& test( decltype(&C::operator<) );
    template <typename C> static NoType& test(...);

public:
    enum { value = sizeof(test<T>(0)) == sizeof(YesType) };
};

template <typename T>
class ConditionalMethodProvided
{
public:
    T x1;
    T x2;
    ConditionalMethodProvided(T&& a1, T&& a2) : x1(a1), x2(a2) {};

    // This and the next method may not be needed at the same time.
    typename std::enable_if<HasLessThan<T>::value, bool>::type
    operator<(ConditionalMethodProvided &other)
    {
        return x1 < other.x1 && x2 < other.x2;
    };

    template <typename U,
              std::enable_if_t<std::is_same_v<U, T>, bool> = true>
    auto operator< (ConditionalMethodProvided<U> & oth)
        -> decltype( std::declval<U>() < std::declval<U>(), bool{} )
        { return x1 < oth.x1 && x2 < oth.x2; }
};

class TypeWithLessThan
{
public:
  int x;
  TypeWithLessThan(int x) : x(x) {};
  bool operator<(TypeWithLessThan &other) {return x < other.x;};
};

int main(int argc, char *argv[])
{
    // The question is how to to make the next two types, int and TypewithLessThan both make the templated class ConditionalMethodProvided to provide the operator< method.
    ConditionalMethodProvided C(TypeWithLessThan(2),     TypeWithLessThan(3));
    ConditionalMethodProvided D(TypeWithLessThan(5),     TypeWithLessThan(7));
    std::cout << (C < D) << std::endl;

    ConditionalMethodProvided E(2,3);
    ConditionalMethodProvided F(5,7);
    std::cout << (E < F) << std::endl;

    return 0;
}
max66

次のようにどうですか?

template <typename T>
class SometimesComparable
 {
   public:
      T x1;
      T x2;

      template <typename U, 
                std::enable_if_t<std::is_same_v<U, T>, bool> = true>
      auto operator< (SometimesComparable<U> const & oth)
         -> decltype( x1 < oth.x1, bool{} )
       { return x1 < oth.x1 && x2 < oth.x2; }
 };

つまり... SFINAEでメソッドを有効/無効にする場合は、メソッドをテンプレートにする必要があるため、

  template <typename U>
  bool operator< (SometimesComparable<U> const & oth)
   { /* something */ }

しかし、私はあなたがそれをしたいと仮定UしてT、あなたがこのthrougを課すことができるように、同じタイプですstd::enable_if_t

  template <typename U, 
            std::enable_if_t<std::is_same_v<U, T>, bool> = true>
  bool operator< (SometimesComparable<U> const & oth)
   { /* something */ }

ここで、SFINAEで演算子を有効にする必要がありますx1 < oth.x1(演算子が定義されている場合U)。したがってauto、末尾の戻り値の型とを使用してdecltype()、次のように記述できます。

  auto operator< (SometimesComparable<U> const & oth)
     -> decltype( x1 < oth.x1, bool{} )
   { /* something */ }

または単にdecltype( x1 < oth.x1 )それが価値x1 < oth.x1与えると確信しているbool場合。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ネストされた列挙型のテンプレートパラメーターでオーバーロードするC ++フレンド演算子

分類Dev

C ++-演算子のオーバーロードを使用してconstテンプレートタイプとnon-constテンプレートタイプを比較することはできません

分類Dev

演算子をテンプレートでオーバーロードしますが、再定義を防ぎます

分類Dev

オーバーロードされた代入演算子を使用するとエラーが発生するのに、コンパイラが提供する演算子を使用できないのはなぜですか?

分類Dev

クラスとintパラメータをテンプレートとして使用するC ++オーバーロード演算子+

分類Dev

Goで.htmlテンプレートを提供する場合、メディアをロードしません

分類Dev

タイプエイリアスを使用するテンプレートのストリーム出力演算子<<にオーバーロードを提供するにはどうすればよいですか?

分類Dev

`std :: ostream`演算子をオーバーロードするときにデフォルトの非タイプテンプレートパラメータを変更する方法はありますか?

分類Dev

ostreamでstd :: endlを使用する '<<'-バリアントメンバーを含む可変個引数テンプレートクラスでの演算子のオーバーロードにより、コンパイラエラーが発生する

分類Dev

C ++ 20の概念では、演算子のオーバーロードとユーザー定義のテンプレート演算子のオーバーロード関数を組み合わせる必要があります

分類Dev

汎用テンプレートを使用してクラスの演算子をオーバーロードするにはどうすればよいですか?

分類Dev

非型パラメータを持つC ++テンプレートクラス:割り当て演算子をオーバーロードする方法は?

分類Dev

条件演算子を使用しているときにテンプレート化された値または関数を再帰的に計算するときのエラーC1202(スタックオーバーフロー)

分類Dev

演算子のオーバーロードと異なるテンプレートパラメータ

分類Dev

標準ライブラリ演算子と競合することなく、関連するクラスのグループの演算子をテンプレートオーバーロードするにはどうすればよいですか?

分類Dev

テンプレート化されたSTLコンテナを取得するために挿入演算子をオーバーロードできますか?

分類Dev

libc ++を使用してClangで逆ベクトルイテレータを使用する場合、「オーバーロードされた演算子の使用があいまいです」

分類Dev

ビルトインクラスのモンキーパッチを使用できますか?そうでない場合、2つの異なるクラスの加算を定義するために演算子をオーバーロードするにはどうすればよいですか?

分類Dev

列挙型パラメーターでテンプレートをオーバーロードするときのMSVCコンパイラエラー

分類Dev

クラステンプレートにoperator +を使用して追加をオーバーロードする演算子

分類Dev

オーバーロードされた演算子deleteにデフォルトのパラメーターを設定できますか?

分類Dev

フレンド関数を使用してテンプレートクラスの外部で演算子==をオーバーロードする方法は?

分類Dev

テンプレートがテンプレートパラメータを「オーバーロード」しないのはなぜですか?

分類Dev

テンプレート演算子[]が奇妙なC2676をオーバーロードしています

分類Dev

SQL Serverストアード・プロシージャーは、パラメーターが提供されている場合でもパラメーターを予期します

分類Dev

C ++テンプレート演算子をオーバーロードしてプライベートプロパティにアクセスする方法

分類Dev

テンプレートクラスで[]演算子をオーバーロードする問題

分類Dev

演算子テンプレートを条件付きでコンパイルすると、別の演算子の可用性が変わるのはなぜですか?

分類Dev

テンプレート化された演算子のオーバーロードを特殊化する方法は?

Related 関連記事

  1. 1

    ネストされた列挙型のテンプレートパラメーターでオーバーロードするC ++フレンド演算子

  2. 2

    C ++-演算子のオーバーロードを使用してconstテンプレートタイプとnon-constテンプレートタイプを比較することはできません

  3. 3

    演算子をテンプレートでオーバーロードしますが、再定義を防ぎます

  4. 4

    オーバーロードされた代入演算子を使用するとエラーが発生するのに、コンパイラが提供する演算子を使用できないのはなぜですか?

  5. 5

    クラスとintパラメータをテンプレートとして使用するC ++オーバーロード演算子+

  6. 6

    Goで.htmlテンプレートを提供する場合、メディアをロードしません

  7. 7

    タイプエイリアスを使用するテンプレートのストリーム出力演算子<<にオーバーロードを提供するにはどうすればよいですか?

  8. 8

    `std :: ostream`演算子をオーバーロードするときにデフォルトの非タイプテンプレートパラメータを変更する方法はありますか?

  9. 9

    ostreamでstd :: endlを使用する '<<'-バリアントメンバーを含む可変個引数テンプレートクラスでの演算子のオーバーロードにより、コンパイラエラーが発生する

  10. 10

    C ++ 20の概念では、演算子のオーバーロードとユーザー定義のテンプレート演算子のオーバーロード関数を組み合わせる必要があります

  11. 11

    汎用テンプレートを使用してクラスの演算子をオーバーロードするにはどうすればよいですか?

  12. 12

    非型パラメータを持つC ++テンプレートクラス:割り当て演算子をオーバーロードする方法は?

  13. 13

    条件演算子を使用しているときにテンプレート化された値または関数を再帰的に計算するときのエラーC1202(スタックオーバーフロー)

  14. 14

    演算子のオーバーロードと異なるテンプレートパラメータ

  15. 15

    標準ライブラリ演算子と競合することなく、関連するクラスのグループの演算子をテンプレートオーバーロードするにはどうすればよいですか?

  16. 16

    テンプレート化されたSTLコンテナを取得するために挿入演算子をオーバーロードできますか?

  17. 17

    libc ++を使用してClangで逆ベクトルイテレータを使用する場合、「オーバーロードされた演算子の使用があいまいです」

  18. 18

    ビルトインクラスのモンキーパッチを使用できますか?そうでない場合、2つの異なるクラスの加算を定義するために演算子をオーバーロードするにはどうすればよいですか?

  19. 19

    列挙型パラメーターでテンプレートをオーバーロードするときのMSVCコンパイラエラー

  20. 20

    クラステンプレートにoperator +を使用して追加をオーバーロードする演算子

  21. 21

    オーバーロードされた演算子deleteにデフォルトのパラメーターを設定できますか?

  22. 22

    フレンド関数を使用してテンプレートクラスの外部で演算子==をオーバーロードする方法は?

  23. 23

    テンプレートがテンプレートパラメータを「オーバーロード」しないのはなぜですか?

  24. 24

    テンプレート演算子[]が奇妙なC2676をオーバーロードしています

  25. 25

    SQL Serverストアード・プロシージャーは、パラメーターが提供されている場合でもパラメーターを予期します

  26. 26

    C ++テンプレート演算子をオーバーロードしてプライベートプロパティにアクセスする方法

  27. 27

    テンプレートクラスで[]演算子をオーバーロードする問題

  28. 28

    演算子テンプレートを条件付きでコンパイルすると、別の演算子の可用性が変わるのはなぜですか?

  29. 29

    テンプレート化された演算子のオーバーロードを特殊化する方法は?

ホットタグ

アーカイブ