4

これは、私が抱えている問題を示すための単純化されたコードです。

特定の固定されたインスタンス化のみをコンパイルしたいテンプレート関数があります。

関数宣言は次のとおりです。

// *** template.h ***
int square (int x);
double square (double x);

定義は次のとおりです。

// *** template.cpp ***
#include "template.h"

// (template definition unusually in a code rather than header file)
template <typename T>
T square (T x)
{
    return x*x;
}

// explicit instantiations
template int square (int x);
template float square (float x);

そして、使用例は次のとおりです。

// *** main.cpp ***

#include <iostream>
using namespace std;

#include "template.h"

int main (void)
{
    cout << square(2) << endl;
    cout << square(2.5) << endl;
}

これをコンパイルしようとすると、リンク エラーが発生します。

main.obj : 関数 main で参照されている未解決の外部シンボル "int square(int)"

問題の内容は理解しています。明示的なテンプレートのインスタンス化の関数シグネチャがヘッダー ファイルのものと一致しません。

明示的なテンプレートのインスタンス化の (前方) 宣言の構文は何ですか? テンプレート定義を前方宣言したり、テンプレート定義をヘッダー ファイルに移動したりしたくありません。

価値があるのは、上記のファイルに以下を追加して、ラッパー関数を使用するという回避策があります。

// *** template.cpp ***

// ...

// wrap them [optionally also inline the templates]
int square (int x) { return square<> (x); }
double square (double x) { return square<> (x); }

これはコンパイルされ、期待どおりに動作します。しかし、これは私にはハックのようです。C++ およびテンプレート構文で利用できるものよりも洗練されたものがあるはずです。

どんな助けやヒントも大歓迎です。

4

2 に答える 2

5

ヘッダーで関数テンプレートを宣言する必要があります。

template <typename T>
T square(T x);

現在のように、ヘッダーで 2 つの非テンプレート関数を宣言しますが、これらは決して定義されません。

于 2010-03-23T15:56:44.663 に答える
1

テンプレートをヘッダー ファイルから隠したい場合は、他に方法はありません。int square (int x);と同じ名前マングリングtemplate int square (int x);がなく、C++ はそれを変更する方法を提供しないため、ラッパー関数が必要です。

例として、名前の混合が Visual Studio でどのように異なるかを確認できます。

于 2012-05-21T21:53:29.100 に答える