なぜ私はこれを行うことができるのですか?
template <typename T>
struct A
{
void foo(int);
};
template <>
void A<int>::foo(int)
{
}
しかし、これではありません:
template <typename> struct C {};
template <typename T>
struct A
{
void foo(int);
};
template <typename T>
void A<C<T> >::foo(int)
{
}
2番目のケースでは、GCCは次のエラーを出します。
test.cpp:10:23: error: invalid use of incomplete type 'struct A<C<T> >'
test.cpp:4:8: error: declaration of 'struct A<C<T> >'
編集:
2番目の例が許可されない理由を説明するときは、メンバー関数をテンプレートとして作成しても、どの例が機能し、どの例が機能しないかには影響しないことも考慮してください。つまり、これは引き続き機能します。
template <typename T>
struct A
{
template <typename U>
void foo(U);
};
template <>
template <typename U>
void A<int>::foo(U)
{
}
しかし、これはしません:
template <typename> struct C {};
template <typename T>
struct A
{
template <typename U>
void foo(U);
};
template <typename T>
template <typename U>
void A<C<T> >::foo(U)
{
}
U
したがって、3番目の例は完全な特殊化ではなく(テンプレートパラメータはまだ存在します)、それでも機能するため、関数テンプレートは完全に特殊化することしかできないという理由はありません。