テンプレート関数を明示的にインスタンス化するにはどうすればよいですか?


117

1つの引数を持つテンプレート関数があります。その関数を呼び出さずにその関数をインスタンス化する必要があるということは、明示的にインスタンス化する必要があることを意味します。

私はこの機能を持っています:

template <class T> int function_name(T a) {}

この関数を次のようにインスタンス化しました。

template int function_name<int>(int);

しかし、次のエラーが発生しました:

error: expected primary-expression before 'template'
error: expected `;' before 'template'

回答:


182

[編集2]:コードの書式設定の問題により、元の質問のコードに関して混乱があったことに注意してください。詳細については、AnthonyHatchkinsの回答を参照してください。

関数を(特殊化するなどの代わりに)インスタンス化したい場合は、次のようにします。

template <typename T> void func(T param) {} // definition

template void func<int>(int param); // explicit instantiation.

[編集]明示的なインスタンス化と特殊化に関して(多くの)混乱があるようです。上記で投稿したコードは、明示的なインスタンス化を扱っています特殊化の構文は異なります。特殊化の構文は次のとおりです。

template <typename T> void func(T param) {} // definition

template <> void func<int>(int param) {} // specialization

テンプレートの後の山括弧に注意してください!


3
それはインスタンス化または特殊ですか?
Nawaz、2011

5
違います。テンプレートを明示的にインスタンス化するようコンパイラーに指示できます。詳細については、「C ++の明示的なテンプレートのインスタンス化」のGoogle。
2011

8
@ Nawaz:あなたは間違っています。もちろん、インスタンス化するのは常にコンパイラーです。その行は、テンプレートをインスタンス化するためのプログラマーからコンパイラーへの要求です。あなたがC ++標準のコピーを持っている場合は、読み14.7.2明示的なインスタンス
dribeas -デビッド・ロドリゲスが

16
専門化とは、おそらくその実装を変更しているということです。インスタンス化とは、特定のコンパイルユニットに割り当てることを意味します。おそらく、その一意のアドレスを取得するか、ライブラリ関数として使用可能にするか、膨張を減らすためです。
CashCow

3
@hrnt:そうだと思います。@Ashot:構文にtemplate<>形式がないことに気づきました。彼が書いたものは専門とは異なります。この新しいことを教えてくれた+1。投稿を削除します。:D
Nawaz

20

あなたのコードは正しいです。

エラーメッセージは、ここで引用しなかったコード内の場所に関連しています。

更新:

元のコードは

template <class T> int function_name(T a) {}
template int function_name<int>(int);

そしてそれは正しかった。

しかし、引用されなかったため、次のようになりました

template int function_name(T a) {}
template int function_name(int);

次のエラーを生成します

a.cpp:1: error: explicit instantiation of non-template int function_name
a.cpp:1: error: expected `;' before ‘(’ token
a.cpp:3: error: function_name is not a template function

これはOPが引用したものとは明らかに異なります。

このバリアントでは、2行目<int>は問題ありませんが(ここでは省略できます)、1行目が不良です。コンパイラTは、それがテンプレートパラメータであると推測できません。


技術的には、それは彼のコードではなかった、それはビルの編集:)オリジナルのコードがありましたtemplate int function_name( T a) { }し、template int function_name(int);
hrnt

@hrnt元のコードは正しくフォーマットされていませんでしたが、正しいものでした。もし私がバラジだったら、彼がそれを有用だと思うなら、私は戻ってあなたの答えを受け入れます、それでも私にとって(そしておそらく他の誰にとっても)あなたの答え(それ自体は完全に正しい)は質問に答えません。
アントニーハッチキンズ2014年

@hrnt元のコードがそのように見えたのはあなたの言うとおりです。しかし、推定されたテンプレート引数のため、それはまだ機能します。エラーはOPが引用しなかったコードから発生するというアントニー・ハッチキンズに同意する必要がありますが、あなたの答えは明示的なインスタンス化について知らなかった人々にとっても役立つと思います。
mpark、2014年

ええと、私を例にとってみましょう。明示的なインスタンス化についてのよく忘れられていた知識を更新したいときに、このページをグーグルで検索しましたが、あまり役に立ちませんでした。私については、構文について混乱はありません。明示的なインスタンス化について混乱を引き起こす可能性があるのは、その使用法です
Antony Hatchkins 14年

@AntonyHatchkinsああ、本当-私は元の質問の出所を見ていませんでした。画面にどのように表示されたかだけです。これを+1し、元の回答を修正して、元の質問に関する混乱に注意します。
1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.