テンプレート化されたクラスの基本クラスに基づいてメンバー関数を特殊化するにはどうすればよいですか

シャミ

テンプレートのタイプに基づいて、テンプレートクラスのメンバー関数を特殊化しようとしています。特に、ポリモーフィックタイプに基づいた専門分野が欲しいです。私は構文に苦労してきました。これが明らかにエラーを生成する私の試みです:宣言の2つ以上のデータ型doSomething()

class Base {};
class Derived : public Base {};

template<typename T>
class MyClass
{
public:

  void doSomething();

};

template<>
template<typename T>
typename std::enable_if<std::is_base_of<Derived, T>::value>::type
void MyClass<T>::doSomething() 
{
    // Do something with Derived type
}

template<>
template<typename T>
typename std::enable_if<std::is_base_of<Base, T>::value &&
                       !std::is_base_of<Derived, T>::value>::type
void MyClass<T>::doSomething() 
{
    // So something with Base type
}

template<>
template<typename T>
typename std::enable_if<!std::is_base_of<Derived, T>::value>::type
void MyClass<T>::doSomething() 
{
    // Do something with all other types
}

コンパイルは与える..

error: two or more data types in declaration of 'doSomething'

ところで、私はコンパイルするために以下を取得しましたが、特殊化は実行時に期待どおりに機能しませんでした。基本型と派生型は、特殊化されていないバージョンのを通過することになりdoSomething()ます。

class Base {};
class Derived : public base {};

template<typename T>
class MyClass
{
public:

  void doSomething()
  {
       // Do something for non-specialized types
  }    
};

template<>
void MyClass<Derived>::doSomething() 
{
    // Do something with Derived type
}

template<>
void MyClass<Base>::doSomething() 
{
    // So something with Base type
}

正しい構文は何でしょうか?

ボロフ

doSomethingテンプレートではないという理由だけで専門化することはできませんMyClassはテンプレートであり、クラスを特殊化できますdoSomething各特殊化には1つあります。それが望ましくない場合は、doSomethingテンプレートをオーバーロードする必要があります。SFINAEを機能させるには、SFINAEチェックをdoSomethingパラメーターではなくテンプレートパラメーターで実行する必要がありMyClassます。最後に、あなたのチェックは間違っています。

だからここに私のバージョンがあります:

template<class T> struct MyClass
{
    template <class U = T>
    auto foo() -> std::enable_if_t<std::is_base_of_v<Base, U>
                                   && !std::is_base_of_v<Derived, U>>
    {
        foo_base();
    }

    template <class U = T>
    auto foo() -> std::enable_if_t<std::is_base_of_v<Derived, U>>
    {
        foo_derived();
    }

    template <class U = T>
    auto foo() -> std::enable_if_t<!std::is_base_of_v<Base, U>>
    {
        foo_else();
    }
};

そして、ここに一連のテストがあります:

class Base {};
class Derived : public Base {};
class A : Base {};
class B : Derived {};
class X {};
auto test()
{
    MyClass<Base>{}.foo();      // foo_base
    MyClass<Derived>{}.foo();   // foo_derived
    MyClass<A>{}.foo();         // foo_base
    MyClass<B>{}.foo();         // foo_derived
    MyClass<X>{}.foo();         // foo_else
}

そしてもちろん、私はC ++ 17のクリーンなソリューションについて言及する必要があります。

template<class T> struct MyClass
{
    auto foo() 
    {
        if constexpr (std::is_base_of_v<Derived, T>)
            foo_derived();
        else if constexpr (std::is_base_of_v<Base, T>)
            foo_base();
        else
            foo_else();
    }
};

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

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

編集
0

コメントを追加

0

関連記事

分類Dev

テンプレート化されていないクラスのテンプレート化されたメンバーメソッドを部分的に特殊化するにはどうすればよいですか?

分類Dev

完全に特殊化されたテンプレートクラスの定義の外でテンプレートメンバー関数を定義するにはどうすればよいですか?

分類Dev

完全に特殊化されたテンプレートクラスの定義の外でテンプレートメンバー関数を定義するにはどうすればよいですか?

分類Dev

STLコンテナであるテンプレートパラメータに基づいて、選択したメンバー関数の部分的な特殊化をシミュレートするにはどうすればよいですか?

分類Dev

関数テンプレート(クラステンプレートのメンバー)を明示的に特殊化すると、「部分的な特殊化は許可されていません」というエラーが発生します。なぜですか?

分類Dev

クラステンプレートによって演算子関数タイプを特殊化するにはどうすればよいですか?

分類Dev

テンプレートクラス(すでに指定されている)でテンプレートメンバー関数を特殊化する方法は?

分類Dev

クラステンプレートの非型パラメータを部分的に特殊化するにはどうすればよいですか?

分類Dev

既存のテンプレートクラスを新しいタイプに部分的に特殊化するにはどうすればよいですか?

分類Dev

クラステンプレートの特殊化を使用してエイリアステンプレートの特殊化を作成するにはどうすればよいですか?

分類Dev

C ++のクラステンプレートに、特殊化されていない共通の静的メンバーを含めることは可能ですか?

分類Dev

列挙値のクラステンプレートを部分的に特殊化するにはどうすればよいですか?

分類Dev

部分的なクラステンプレートの特殊化で継承を実装するにはどうすればよいですか?

分類Dev

C ++ 11では、戻り値の型に基づいて関数オブジェクトを受け取る関数テンプレートを特殊化するにはどうすればよいですか?

分類Dev

テンプレートの特殊化が基本テンプレートの子クラスであるかどうかを確認するにはどうすればよいですか?

分類Dev

メンバーパラメータへのポインタを持つテンプレートクラスを特殊化するにはどうすればよいですか?

分類Dev

インスタンス化されている場合、テンプレート化された変数の特殊化をコンパイル時に失敗させるにはどうすればよいですか?

分類Dev

関数テンプレートの特殊化を減らすにはどうすればよいですか?

分類Dev

C ++「新しい」タイプのテンプレートを特殊化するときに、コンストラクターパラメーターを事前定義するにはどうすればよいですか。

分類Dev

クラスを特殊化する場合、異なる数のテンプレートパラメータを取得するにはどうすればよいですか?

分類Dev

テンプレート化されたクラスを引数の型として使用するにはどうすればよいですか?

分類Dev

テンプレートパラメータに基づいて関数を「有効化」するにはどうすればよいですか?

分類Dev

テンプレート関数をテンプレート化されたネストされたクラスのフレンドとして宣言するにはどうすればよいですか?

分類Dev

非型テンプレートクラスを特殊化するために、宣言の外部でメソッドを定義するにはどうすればよいですか?

分類Dev

C ++が完全な特殊化によってマスクされている基本テンプレート関数をインスタンス化するのはなぜですか?

分類Dev

すでに特殊化されたクラスのメンバー関数の特殊化

分類Dev

STLソートを使用して、テンプレートの特殊化を使用してカスタムクラスオブジェクトをソートするにはどうすればよいですか?

分類Dev

可変個引数を使用してこのテンプレートの特殊化をクラスの友達にするにはどうすればよいですか?

分類Dev

Clangは、クラステンプレートのネストされたクラスが特殊化によってのみ定義されているコードを拒否することは正しいですか?

Related 関連記事

  1. 1

    テンプレート化されていないクラスのテンプレート化されたメンバーメソッドを部分的に特殊化するにはどうすればよいですか?

  2. 2

    完全に特殊化されたテンプレートクラスの定義の外でテンプレートメンバー関数を定義するにはどうすればよいですか?

  3. 3

    完全に特殊化されたテンプレートクラスの定義の外でテンプレートメンバー関数を定義するにはどうすればよいですか?

  4. 4

    STLコンテナであるテンプレートパラメータに基づいて、選択したメンバー関数の部分的な特殊化をシミュレートするにはどうすればよいですか?

  5. 5

    関数テンプレート(クラステンプレートのメンバー)を明示的に特殊化すると、「部分的な特殊化は許可されていません」というエラーが発生します。なぜですか?

  6. 6

    クラステンプレートによって演算子関数タイプを特殊化するにはどうすればよいですか?

  7. 7

    テンプレートクラス(すでに指定されている)でテンプレートメンバー関数を特殊化する方法は?

  8. 8

    クラステンプレートの非型パラメータを部分的に特殊化するにはどうすればよいですか?

  9. 9

    既存のテンプレートクラスを新しいタイプに部分的に特殊化するにはどうすればよいですか?

  10. 10

    クラステンプレートの特殊化を使用してエイリアステンプレートの特殊化を作成するにはどうすればよいですか?

  11. 11

    C ++のクラステンプレートに、特殊化されていない共通の静的メンバーを含めることは可能ですか?

  12. 12

    列挙値のクラステンプレートを部分的に特殊化するにはどうすればよいですか?

  13. 13

    部分的なクラステンプレートの特殊化で継承を実装するにはどうすればよいですか?

  14. 14

    C ++ 11では、戻り値の型に基づいて関数オブジェクトを受け取る関数テンプレートを特殊化するにはどうすればよいですか?

  15. 15

    テンプレートの特殊化が基本テンプレートの子クラスであるかどうかを確認するにはどうすればよいですか?

  16. 16

    メンバーパラメータへのポインタを持つテンプレートクラスを特殊化するにはどうすればよいですか?

  17. 17

    インスタンス化されている場合、テンプレート化された変数の特殊化をコンパイル時に失敗させるにはどうすればよいですか?

  18. 18

    関数テンプレートの特殊化を減らすにはどうすればよいですか?

  19. 19

    C ++「新しい」タイプのテンプレートを特殊化するときに、コンストラクターパラメーターを事前定義するにはどうすればよいですか。

  20. 20

    クラスを特殊化する場合、異なる数のテンプレートパラメータを取得するにはどうすればよいですか?

  21. 21

    テンプレート化されたクラスを引数の型として使用するにはどうすればよいですか?

  22. 22

    テンプレートパラメータに基づいて関数を「有効化」するにはどうすればよいですか?

  23. 23

    テンプレート関数をテンプレート化されたネストされたクラスのフレンドとして宣言するにはどうすればよいですか?

  24. 24

    非型テンプレートクラスを特殊化するために、宣言の外部でメソッドを定義するにはどうすればよいですか?

  25. 25

    C ++が完全な特殊化によってマスクされている基本テンプレート関数をインスタンス化するのはなぜですか?

  26. 26

    すでに特殊化されたクラスのメンバー関数の特殊化

  27. 27

    STLソートを使用して、テンプレートの特殊化を使用してカスタムクラスオブジェクトをソートするにはどうすればよいですか?

  28. 28

    可変個引数を使用してこのテンプレートの特殊化をクラスの友達にするにはどうすればよいですか?

  29. 29

    Clangは、クラステンプレートのネストされたクラスが特殊化によってのみ定義されているコードを拒否することは正しいですか?

ホットタグ

アーカイブ