1

テンプレートについての私自身の理解に課題を見つけました。テンプレートがインスタンス化されているすべての依存型にアクセスするには、テンプレートのソースコードをヘッダーファイルに配置する必要があることを理解しています。

したがって、この例では:

// This code cannot be placed in the cpp file
template <typename T> T foo(T v)
{
    return -v;
}

の本文はT foo(T v)ヘッダーファイルに配置する必要があります。foo関数がどこかにインスタンス化されると、「実際の」本文関数が作成され、Tシンボルが実際の型に置き換えられます。このコードで:

int bar = 5;
float baz = 6.66f;
bar = foo<int>(bar);
baz = foo<float>(baz);

テンプレートのインスタンス化メカニズムは、以前に定義されたテンプレートに基づいて次の関数を作成します。

int foo(int v)
{
    return -v;
}

float foo(float v)
{
    return -v;
}

ただし、テンプレートクラスがある場合、そのクラスには、依存型をまったく使用しない関数を含めることができます。

template <typename T> class Foo
{
    Foo() : mistery(0), value(0) {}; // We're using the dependant type.
    AddMistery() { ++mistery; }; // We are not using the dependant type.

    int mistery;
    T value;
};

AddMisteryこのメソッドは依存型を使用していないため、このメソッドをcppファイルに配置できると最初に考えましたが、試したところ、リンク中に失敗しました。この時点で、テンプレートクラスのさまざまなインスタンスが同じクラスではないことを思い出して、顔を平手打ちしました。したがって、リンカがその仕事をしているとき、AddMisteryメソッドの本体を探しますが、irがcppファイルに配置されているため、それは見つかりません。

// Foo.h
template <typename T> class Foo
{
    Foo() : mistery(0), value(0) {}; // We're using the dependant type.
    AddMistery(); // We are not using the dependant type.

    int mistery;
    T value;
};

// Foo.cpp
#include "Foo.h"

template <typename T> Foo<T>::AddMistery()
{
    ++mistery;
}

// Main.cpp
#include "Foo.h"

int main(int argc, char **argv)
{
    Foo<int> i;
    Foo<float> f;

    i.AddMistery(); // Link Error, where's the Foo<int>::AddMistery body?
    f.AddMistery(); // Link Error, where's the Foo<float>::AddMistery body?

    return 0;
};

それで、最後に、ここに質問があります:すべてのメソッドの本体をヘッダーファイルに保持する代わりに、型に依存しないすべてのメソッドの本体をcppに移動して、ヘッダーとcppファイルの間でテンプレートクラスを分割する方法がありますか?

4

2 に答える 2

1

特定のテンプレートパラメータを使用してインスタンス化しない限り、クラステンプレートはクラスではないため、簡単な答えはノーです。したがってFoo::AddMystery()、実装する必要はありません。

このように考えてください。メンバー関数は、クラスのオブジェクトへのポインターである暗黙の最初のパラメーターを持っているため、依存型の知識を持っています。それで

Foo<int> f;
f.AddMistery();

と同等です

Foo<int> f;
Foo<int>::AddMistery(&f);

特定のタイプのテンプレートのインスタンス化がある場合は、たとえばファイルに実装できますが、これは、本体にテンプレート引数を必要としない関数とは関係ありません。Foo<int>::AddMistery.cpp

于 2012-08-31T11:03:02.373 に答える
1

テンプレートを、、、などの限られた既知のタイプのセットでのみ使用することを意図しない限り、それは不可能intです。この場合、明示的なインスタンス化を使用して、テンプレート関数の定義をファイルに配置できます。shortdouble.cpp

于 2012-08-31T11:12:29.423 に答える