4
#define Create_Function(Type) \
    template void Function( std::vector<boost::shared_ptr<Type>>&)

Create_Function(std::string);

上記のコードをレガシーコードで見ましたが、その意味がわかりません。これは、通常の特殊化されていない関数定義でも、完全に特殊化された関数定義でもありません。

何か案が?

4

2 に答える 2

4

明示的なテンプレートのインスタンス化を行います(MSDNを参照) 。

明示的なインスタンス化を使用すると、コードで実際に使用しなくても、テンプレート化されたクラスまたは関数のインスタンス化を作成できます。これは、配布にテンプレートを使用するライブラリ(.lib)ファイルを作成するときに役立つため、インスタンス化されていないテンプレート定義はオブジェクト(.obj)ファイルに入れられません。

与えられた一般的な関数テンプレート

template<typename T>
void Function( std::vector<boost::shared_ptr<T>>&)
{
    // bla bla
}

マクロの呼び出しは次のようにCreate_Function(std::string);展開されます

template void Function( std::vector<boost::shared_ptr<std::string>>&);
于 2012-08-16T14:13:43.593 に答える
3

これは、関数テンプレートの明示的なインスタンス化です。次のようなテンプレートが与えられます:

template <typename T>
void Function( std::vector<boost::shared_ptr<T> >& );

(おそらくヘッダーで宣言され、.cppファイルで定義されています)、コード:

template void Function( std::vector<boost::shared_ptr<int> >& );

コンパイラがこの変換ユニットの特殊化をインスタンス化(コードを生成)する必要があります。テンプレートのユーザーはテンプレートの宣言を確認するだけでよく、使用される各変換ユニットでテンプレートをインスタンス化しないため、これを使用してコンパイル時間を短縮できます。欠点としては、そのテンプレートで使用されるタイプごとに、テンプレートの定義にアクセスできる変換ユニットで明示的なインスタンス化を実行する必要があります。これにより、テンプレートの使用がそれらのインスタンス化に制限されます。

// tmpl.h
template <typename T>
void Function( std::vector<boost::shared_ptr<T> >& );

// tmpl.cpp
template <typename T>
void Function( std::vector<boost::shared_ptr<T> >& p ) {
    ... 
}
template void Function( std::vector<boost::shared_ptr<int> >& );
template void Function( std::vector<boost::shared_ptr<double> >& );

// user.cpp, user2.cpp, user3.cpp
#include <tmpl.h>
...
    std::vector<boost::shared_ptr<int> > v;
    Function( v );                             // [1]

この例では、「user#.cpp」をコンパイルするときに、「tmpl.cpp」でのみテンプレートを使用するすべての変換ユニットでFunctionテンプレートのインスタンス化のコストが発生しないため、コンパイル時間が短縮される可能性があります。

インスタンス化タイプを、明示的なインスタンス化を提供したサブセットに効果的に制限できるため、実際には欠点がこのアプローチの理由である場合があります(つまり、上記のコードでは、「userN.cpp」がベクトルの受け渡しを呼び出そうとした場合Function)リンカへの共有ポインタの数std::stringは文句を言います)。

最後に、いくつかのケースでは、使用できるタイプのセットが限られている場合に、ライブラリのユーザーからテンプレートの実際の実装を隠す方法として見ました。

于 2012-08-16T14:23:59.380 に答える