Необходимо указать, что класс inner
является имя типа , поскольку он зависит от параметра шаблона, а компилятор C ++ предполагает, что имя inner
в этом контексте не тип:
template <class t> typename outer<t>::inner* outer<t>::m;
Обоснование: имя inner
в приведенной выше строке зависит от имени типа, t
. Компилятор C ++ на данный момент не знает, что такое inner
, потому что значение имени inner
может отличаться в зависимости от t
. Например, предположим, что где-то еще в коде есть специализированная версия класса outer
для int
:
template <>
class outer<int> {
int inner;
};
Теперь outer<int>::inner
больше не называет тип; он называет переменную-член.
Таким образом, в общем случае значение outer<t>::inner
будет неоднозначным, и C ++ разрешает эту неоднозначность, предполагая, что inner
не называет тип. Если вы не говорите, что это так, префиксом его с typename
: typename outer<t>::inner
. (В этом контексте inner
называется зависимым именем , поскольку оно зависит от точного типа t
.)