3

いくつかの特定の型パラメーターのみを受け入れるテンプレートクラス ( と呼びましょうFoo) を作成したいと思います ( と のみdoubleとしましょうfloat)。通常、テンプレートはヘッダー ファイル ( .h) に実装されます。これは、ユーザー コードでテンプレートがどのようにインスタンス化されるかがわからないためです。.cppこの場合、次のように実装ファイル ( )でクラスを実装する方が理にかなっています。

// Foo.cpp:

template <class T>
class Foo
{
    // Insert members here
};

typedef Foo<double> Foo_d;
typedef Foo<float> Foo_f;

これにより、Foo.cpp のコンパイル時にクラスがインスタンス化およびコンパイルされます。Foo_dしかし、との別々の宣言を書かずにヘッダーファイルでこれを宣言するにはどうすればよいFoo_fですか?

4

2 に答える 2

6

ヘッダー ファイルでテンプレートを定義し、メソッドを宣言できますが、メソッドを定義する必要はありません。例えば:

template <typename T>
class Foo {
    T val;
public:
    Foo (T t);
    T value ();
};

typedef Foo<double> Foo_d;
typedef Foo<float> Foo_f;

この.cppファイルでは、メソッドの実装を完了してから、必要なテンプレートをインスタンス化します。

#include "foo_template.hpp"

template <typename T>
Foo<T>::Foo (T t) : val(t) {}

template <typename T>
T Foo<T>::value () { return val; }

template class Foo<double>;
template class Foo<float>;

オブジェクト ファイルには、 templateの明示的なインスタンス化に対するインスタンス化Foo_dと、明示的なインスタンス化Foo_fからのインスタンス化が必要です。テンプレートに他のタイプを使用すると、それらのインスタンス化が存在しないため、リンク エラーが発生します。または、より衒学的なことに、コンパイラは通常どおりオンデマンドでインスタンス化を作成しますが、クラスのメソッドに対応するシンボルを解決することはできません。それらの明示的なインスタンス化が存在しないためです。FooFoo

于 2012-06-12T01:07:42.460 に答える
5

私が間違っていない限り、あなたが説明していることはまさに新しい C++11extern template機能の使用例です。この機能を使用するには、テンプレート クラスのインターフェイスをヘッダー ファイルに配置します。次に、ヘッダー ファイルを次の行で終了します。

extern template class Foo<float>;
extern template class Foo<double>;

これにより、ヘッダー ファイルをインクルードするすべてのファイルに対して、使用時にテンプレートのインスタンス化を試行しないように指示されます。次に、C++ ファイルでテンプレート クラスを実装し、次の行で終了します。

template class Foo<float>;
template class Foo<double>;

これらの最後の 2 行により、コンパイラはこの翻訳単位でテンプレートをインスタンス化するように強制されるため、リンカー エラーは発生しません。

お役に立てれば!

于 2012-06-12T00:45:24.963 に答える