テンプレートの特殊化の問題は、テンプレート パラメーターがどこにも使用されていないため、通常の関数のように扱われることです。
そのため、次のコードをヘッダー ファイルに入れると、最初は機能します。
template <typename foo>
void f(foo p)
{
std::cout << "f one" << std::endl;
}
template <>
void f<int>(int p)
{
std::cout << "f two" << std::endl;
}
ただし、ヘッダーが 2 つのファイルに含まれていると、これは機能しなくなります。この場合、(VS2010で)得られるエラーは次のとおりです。
templateordering.obj : error LNK2005: "void __cdecl f<int>(int)" (??$f@H@@YAXH@Z) already defined in othertu.obj
これは、他の多くの質問で述べられているように、インラインキーワードを使用することで修正できます。
template <>
inline void f<int>(int p)
{
std::cout << "f two" << std::endl;
}
今、これは私に2つの質問を提起します:
- これを行う他の方法はありますか?ソースファイルに特殊な関数を入れてもうまくいかないようです。おそらく、ヘッダーに何らかの宣言が必要になるためです。
- インラインは実際に何をしますか?インラインは使用すべきではないというのは、インターネット全体で一般的な経験則のようです。コンパイラは「いずれにせよ、関数を好きなようにインライン展開する可能性が高い」からです。では、コンパイラが「インライン」として宣言した関数をインライン化しない可能性がある場合、なぜこれが機能するのでしょうか?