web-dev-qa-db-ja.com

C ++テンプレート特化構文

C++ Primer Plus(2001、チェコ語翻訳)で、これらの異なるテンプレート特化構文を見つけました。

関数テンプレート

template <typename T> void foo(T);

特殊化構文

void foo(int param); // 1
void foo<int>(int param); // 2
template <> void foo<int>(int param); // 3
template <> void foo(int param); // 4
template void foo(int param); // 5

少しグーグルで、私はNo.3の例を見つけました。それらの間に何か違いはありますか(呼び出し、コンパイル、使用)?それらのいくつかは廃止/廃止されていますか?なぜNo.1を使用しないのですか?

48
Jan Turoň

各構文のコメントは次のとおりです。

void foo(int param); //not a specialization, it is an overload

void foo<int>(int param); //ill-formed

//this form always works
template <> void foo<int>(int param); //explicit specialization

//same as above, but works only if template argument deduction is possible!
template <> void foo(int param); //explicit specialization

//same as above, but works only if template argument deduction is possible!
template void foo(int param); //explicit instantiation

私が追加した:

//Notice <int>. This form always works!
template void foo<int>(int param); //explicit instantiation

//Notice <>. works only if template argument deduction is possible!
template void foo<>(int param); //explicit instantiation

コーディングの観点からは、関数テンプレートの専門化よりもオーバーロードが優先されます。

したがって、関数テンプレートを専門にしないでください:

また、用語を知るには:

  • インスタンス化
  • 明示的なインスタンス化
  • 専門化
  • 明示的な特殊化

こちらをご覧ください:

75
Nawaz

Visual Studio 2012を使用している場合、関数の引数がない場合はわずかに異なる動作をするようです:

template <typename T> T bar( );
//template int bar<int>( ) { return 0; } doesn't work
template < > int bar<int>( ) { return 0; } //does work
1
gerardw