クラス内でテンプレート関数を作成する方法は?(C ++)


144

テンプレート関数を作成できることはわかっています。

template<typename T>
void DoSomeThing(T x){}

そして、テンプレートクラスを作ることが可能です:

template<typename T>
class Object
{
public:
    int x;
};

しかし、テンプレート内にないクラスを作成し、そのクラスの関数をテンプレートにすることは可能ですか?すなわち:

//I have no idea if this is right, this is just how I think it would look
class Object
{
public:
    template<class T>
    void DoX(){}
};

または、クラスはテンプレートの一部ではないが、機能はある程度ですか?

回答:


115

あなたの推測は正しいものです。覚えておかなければならない唯一のことは、(宣言に加えて)メンバー関数テンプレートの定義は、クラス宣言自体の本体にある必要はありませが、cppではなくヘッダーファイルにある必要があるということです。


3
また、それらを特化することはできません。:-(
フランククルーガー

7
正確ではない。定義は、非テンプレート関数/メソッドから定義された後に、一意のテンプレートパラメータn-upletごとに1回呼び出される限り、cppファイルに含めることができます。
ブノワ

1
したがって、私の「すべき」-それをヘッダーに保持することは、それを達成する最も簡単な方法です。
わからない

4
実際、あなたはそれらを明示的に特化することができると信じていますが、それらを部分的に特化することはできません。残念ながら、これがコンパイラ固有の拡張なのか、C ++標準なのかはわかりません。
パトリックジョンマイヤー2009年

7
実際には標準のc ++です。struct A {template <typename> void f();を実行できます。}; template <> void A :: f <int>(){}など。それらをクラススコープで特殊化することはできませんが、名前空間スコープで行うとうまく機能します。(スペシャライゼーションが実際に挿入されるスコープと混同しないでください。スペシャライゼーションは引き続きクラスのメンバーですが、その定義はネームスペーススコープで行われます。多くの場合、何かが挿入されるスコープはスコープと同じです。何かが定義されている-しかし、クラス外の定義のすべてのケースのように、それが正しくない場合もあります)
Johannes Schaub-litb 09年

70

ここを参照してください:テンプレートテンプレートメソッド、メンバーテンプレート、メンバー関数テンプレート

class   Vector
{
  int     array[3];

  template <class TVECTOR2> 
  void  eqAdd(TVECTOR2 v2);
};

template <class TVECTOR2>
void    Vector::eqAdd(TVECTOR2 a2)
{
  for (int i(0); i < 3; ++i) array[i] += a2[i];
}

良い例え。しかし、なぜtemplate <typename T>がクラスdefinitinoの中にあるのですか... ???
Martian2049

@ Martian2049これはテンプレートがクラス全体ではなくクラス内のメンバー関数にのみ適用されるためだと思います。まさにOPが尋ねたとおり。
CBK

21

はい、テンプレートメンバー関数は完全に合法であり、多くの場合に役立ちます。

唯一の注意点は、テンプレートメンバー関数を仮想化できないことです。


9

最も簡単な方法は、宣言と定義を同じファイルに入れることですが、サイズが大きすぎる実行可能ファイルが発生する可能性があります。例えば

class Foo
{
public:
template <typename T> void some_method(T t) {//...}
}

また、テンプレート定義を個別のファイルに配置することもできます。つまり、それらを.cppファイルと.hファイルに配置できます。必要なのは、テンプレートのインスタンス化を.cppファイルに明示的に含めることだけです。例えば

// .h file
class Foo
{
public:
template <typename T> void some_method(T t);
}

// .cpp file
//...
template <typename T> void Foo::some_method(T t) 
{//...}
//...

template void Foo::some_method<int>(int);
template void Foo::some_method<double>(double);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.