7

仮想関数を持つ基本クラスがあります。

class Base
{
public:
  virtual void Function();
};

void Base::Function()
{
  cout << "default version" << endl;
}

および派生テンプレート クラス:

template <class T> class Derived : public Base
{
public:
  virtual void Function();
};

Function()一部の選択されたものを除いて、すべてのタイプの基本クラスから取得する方法はありますか? Function()したがって、私が望むのは、たとえばintandのオーバーライドを定義できるようにすることですlong

void Derived<int>::Function()
{
  cout << "overriden version 1" << endl;
}

void Derived<long>::Function()
{
  cout << "overriden version 2" << endl;
}

Function()を明示的に定義せずに、他のすべてのタイプのデフォルトバージョンをFunction()使用するため、の出力

int main ()
{
  Derived<int> derivedInt;
  derivedInt.Function();

  Derived<long> derivedLong;
  derivedLong.Function();

  Derived<double> derivedDouble;
  derivedDouble.Function();
}

だろう

overriden version 1
overriden version 2
default version

出来ますか?

4

3 に答える 3

8

クラス テンプレートのメンバー関数は、実際には関数テンプレートであるため、それらを特殊化できます。

template <typename T> class Foo
{
    void Function();
};

template <typename T> void Foo::Function() { /* ... */ }

template <> void Foo<int>::Function() { /* ... */ }
于 2012-06-02T15:29:58.180 に答える
4

最初の解決策typeid演算子の使用)

#include <iostream>
#include <typeinfo>

using namespace std;

class Base
{
public:
    virtual void Function();
};

void Base::Function()
{
    cout << "default version\n";
}

template<typename T>
class Derived : Base
{
public:
    virtual void Function();
};

template<typename T>
void Derived<T>::Function()
{
    if(typeid(T) == typeid(int)) // check if T is an int
    {
        cout << "overriden version 1\n";
    }
    else if(typeid(T) == typeid(long)) // check if T is a long int
    {
        cout << "overriden version 2\n";
    }
    else // if T is neither an int nor a long
    {
        Base::Function(); // call default version
    }
}

int main()
{
    Derived<int> di;
    Derived<long> dl;
    Derived<float> df;

    di.Function();
    dl.Function();
    df.Function();

    return 0;
}

typeid演算子を使用して、 T が anintまたは a のいずれかであるかどうかを確認しlong int、そうである場合は、「オーバーライドされたバージョン [番号]」を出力します。Base::Function()そうでない場合は、 「デフォルト バージョン」を出力するを呼び出します。

注:演算子を使用するtypeidには、ヘッダー ファイルを含める必要がありますtypeinfo

2番目の解決策(テンプレートの特殊化を使用)

// class declarations as before

template<typename T>
void Derived<T>::Function()
{
    Base::Function(); // call default version
}

template<>
void Derived<int>::Function()
{
    cout << "overriden version 1\n";
}

template<>
void Derived<long>::Function()
{
    cout << "overriden version 2\n";
}

int main()
{
    Derived<int> di;
    Derived<long> dl;
    Derived<float> df;

    di.Function();
    dl.Function();
    df.Function();

    return 0;
}

ここでは、テンプレートの特殊化に関する問題を解決します。T が anintまたは aの場合long int、特殊化されたバージョンを呼び出します。それ以外の場合は、 と同等の一般的なバージョンを呼び出しますBase::Function()

于 2012-06-02T18:11:01.393 に答える
3

はい、専門化することによってDerived

  • それなしで汎用バージョンを記述します(から継承しますBase
  • Derivedオーバーライドするために特化

シンプルなスキームですが、うまくいきます。

于 2012-06-02T15:14:50.517 に答える