1

重複の可能性:
テンプレートをヘッダー ファイルにしか実装できないのはなぜですか?

テンプレート関数と、関数 main で型 int の呼び出しを作成しました。

template <class T> T max (T a, T b) {    }
int main() {
    max(1,2);
}

ほとんどの C++ の書籍で述べられているように、int max(int,int)関数は、コンパイラがmax(1,2).

しかし、別のファイルに の宣言を書いてint max(int,int)呼び出したのですが、コンパイラ (実際にはリンカ) が の参照がmax(int,int)見つからないというエラーをキャッチしました。

extern int max(int,int);
max(1,2);    // Error:undefined reference to max(int,int)

では、何が問題なのか、ヘッダー ファイル宣言ではなく extern を使用して max(int,int) 関数を呼び出す方法を教えてください。

どうもありがとう。

4

3 に答える 3

2

この質問は数千回しか回答されていません。短い形式は次のとおりです。コンパイラが関数テンプレートを暗黙的にインスタンス化できるように、使用時にテンプレート定義が表示されるように調整するか、関数テンプレートを明示的にインスタンス化する必要があります。

宣言は、パラメータとして2 つを取るextern int max(int, int);非テンプレート関数を宣言していることに注意してください。この参照は、インスタンス化されているかどうかにかかわらず、関数テンプレートによって満たされることはありません。max()int

于 2012-12-27T12:04:03.050 に答える
1

extern int max(int,int);非テンプレート関数を宣言します。他のファイルに表示されていたとしても、テンプレートと一致しません。

正しい方法は、テンプレートをヘッダーに配置し、関数が使用されるすべての場所に含めることです (または、max標準ライブラリで既に利用可能なテンプレートを使用することをお勧めします)。

于 2012-12-27T12:12:26.203 に答える
0

宣言するときはextern int max(int, int)、必ずしも同じ翻訳単位ではなく、どこかで定義されたこのシグネチャを持つ関数があることをコンパイラに伝えます。extern関数にはデフォルトで外部リンケージがあるため、実際には冗長です。

さて、この宣言は、T = int を使用したテンプレート関数のインスタンス化の定義を提供すると考えているようです。そうではありません。2つはまったく関係がありません。コンパイラが呼び出しの候補を検索するときは、関数テンプレートよりも単純な関数が優先されますmax(1,2)。宣言が見つかるとint max(int, int)、それは完全に一致し、その仕事は完了です。テンプレートをインスタンス化しようとさえしません。コンパイルが完了すると、リンカーは定義を見つけることになっていますが、定義を提供していないため、未定義の参照が取得されます。

したがって、定義を書くことができます

int max(int, int) { }

または、テンプレートを使用するようにコンパイラに明示的に指示します

max<int>(1,2);

テンプレートを型に特化することもできますint

template<>
int max<int>(int, int) { };

ただし、通常の機能を維持した場合でも、より適切に一致することに注意してください。

于 2012-12-27T12:29:24.203 に答える