This one compiles and works like it should (non-nested template):
#include
template class Z;
template
This is a general problem for functions:
template
void func(typename C::iterator i);
Now, if I call func(int*), which value of C should I use ?
In general, you cannot work backward ! Many different C could have defined an internal type iterator that happens to be a int* for some set of parameters.
In your case, you are complicating the situation a bit:
template
void func(typename Z::ZZ const&);
But fundamentally this is the same issue, Z is a template, not a full class, and you are asking to create a function for the inner type ZZ of this template.
Suppose I do:
template
struct Z { typedef T ZZ; };
template
struct Z { typedef T ZZ; };
Note: typical of iterators, the value_type is not const-qualified
Then, when invoking func(int), should I use Z or Z ?
It is non-deducible.
And thus the whole thing is referred to as a non-deducible context, and the Standard forbids it because there is no sensible answer.
Rule of Thumb: be suspicious of typename in the parameters of a function.
Note: they are OK if another argument already pinned down the type, example typename C::iterator find(C&, typename C::const_reference); because once C is deduced, then C::const_reference may be used without trouble