operator<<(ostream&, X) for class X nested in a class template

Viewed 1973

This one compiles and works like it should (non-nested template):

#include <iostream>

template<typename T> class Z;

template <typename T> 
std::ostream& operator<< (std::ostream& os, const Z<T>&) {
    return (os << "Z");
}

template<typename T> class Z {
    friend std::ostream& operator<< <> (std::ostream& os, const Z&);
};

int main () {
    Z<int> z;
    std::cout << z << std::endl;
}

This one doesn't compile (gcc 4.4 and gcc 4.6, in both 03 and 0x mode):

#include <iostream>

template<typename T> class Z;

template<typename T> 
std::ostream& operator<< (std::ostream& os, const typename Z<T>::ZZ&) {
    return (os << "ZZ!");
}

template <typename T> class Z {
  public:
    class ZZ {
        friend std::ostream& operator<< <> (std::ostream& os, const ZZ&);
    };
};


int main () {
    Z<int>::ZZ zz;
    std::cout << zz << std::endl;
}

The error message looks like this:

error: template-id ‘operator<< <>’ for ‘std::ostream& operator<<(std::ostream&,
const Z<int>::ZZ&)’ does not match any template declaration
error: no match for ‘operator<<’ in ‘std::cout << zz’

In the 0x mode the second error message is different, but the meaning is the same.

Is it possible to do what I want to do?

EDIT Apparently, there's an instance of non-deduced context here, which explains the error messages. The question, however, still stands: can I have a working operator<< for a class nested in a class template?

4 Answers
Related