Это недействительно:
template< typename T >
struct B< 0, T >::C
{
typedef T type;
};
Вы можете специализировать элементы шаблонов классов, но только для неявных реализаций этих шаблонов классов. Это означает на простом английском языке: только если вы задаете значения для всех аргументов шаблона включающего шаблона класса (член которого вы должны специализировать).
template< >
struct B< 0, int >::C
{
typedef T type;
};
То, что вы написали, это определение B<0, T>::C
, которое является членом частичной специализации шаблона класса B<N, T>
. Такой частичной специализации не существует, поэтому компилятор допустил ошибку.
У вас есть несколько вариантов решения этой проблемы. Одним из них является
template< int N, typename T >
struct B
{
template<typename N1, typename T1>
struct CMember { typedef T1 type[N1]; };
template<typename T1>
struct CMember<0, T1> { typedef T1 type; };
struct C {
typedef typename CMember<N, T>::type type;
};
};
Обратите внимание, что явные специализации (не частичные) не могут быть непосредственно вставлены в шаблон класса (поэтому template<> struct CMember<0, int> { ... }
будет неправильно сформирован при записи в теле B
). Тогда вам потребуется определить шаблон «селектор» вне B
(возможно, в пространстве имен detail
).
Другие альтернативы включают наследование от CMember
и наследование его typedefs.