You need to qualify that the inner
class is a typename, since it’s dependent on a template parameter and the C++ compiler assumes that the name inner
in this context is not a type:
template <class t> typename outer<t>::inner* outer<t>::m;
Rationale: the name inner
in the above line depends on a type name, t
. The C++ compiler at this point doesn’t know what inner
is, because the meaning of the name inner
can differ depending on t
. For example, suppose that, somewhere else in the code, there is a specialized version of the outer
class for int
:
template <>
class outer<int> {
int inner;
};
Now, outer<int>::inner
no longer names a type; it names a member variable.
Thus, in the general case the meaning of outer<t>::inner
would be ambiguous and C++ resolves this ambiguity assuming that inner
does not name a type. Unless you say it does, by prefixing it with typename
: typename outer<t>::inner
. (In this context, inner
is called a dependent name since it depends on the exact type of t
.)