This one compiles and works like it should (non-nested template):
#include
template class Z;
template
Apart from the problem that the friend declaration doesn't match the operator template (perhaps fixable as)
class ZZ {
template
friend std::ostream& operator<<(std::ostream& os, const ZZ&);
};
you also have a problem with a "non-deduced context", which is what Matthieu links to.
In this template
template
std::ostream& operator<< (std::ostream& os, const typename Z::ZZ&) {
return (os << "ZZ!");
}
the compiler isn't able to figure out for what T's you parameter will match. There could be several matches, if you specialize for some types
template<>
class Z
{
public:
typedef double ZZ;
};
template<>
class Z
{
public:
typedef double ZZ;
};
Now if I try to print a double, T could be either bool or long.
The compiler cannot know this for sure without checking for all possible T's, and it doesn't have to do that. It just skips your operator instead.