https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72104
Bug ID: 72104 Summary: Inner templated class with stream operator fails to compile Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: romain.geissler at amadeus dot com Target Milestone: --- Hi, I am having issues with code that used to build fine with gcc 4.9 and 5.3, but doesn't work anymore with gcc 6.1.1 (20160725). I am not actually sure this is valid C++ though... cat test.cpp 11:38PM #include <iostream> // The following two lines are required to build with clang. //template <typename T> class UnrelatedClass; //template <typename T> std::ostream& operator<<(std::ostream&, const UnrelatedClass<T>&); class TopLevelClass { private: template <typename T> class InnerClass; template <typename T> friend std::ostream& operator<<(std::ostream&, const TopLevelClass::InnerClass<T>&); template <typename T> class InnerClass { friend std::ostream& operator<< <>(std::ostream&, const TopLevelClass::InnerClass<T>&); int _x; }; public: void f(std::ostream& ioStream); }; template <typename T> std::ostream& operator<<(std::ostream& ioStream, const TopLevelClass::InnerClass<T>& iInnerClass) { ioStream << iInnerClass._x << std::endl; return ioStream; } void TopLevelClass::f(std::ostream& ioStream) { InnerClass<int> aInnerClass; ioStream << aInnerClass; } int main() { TopLevelClass aTopLevelClass; aTopLevelClass.f(std::cout); } /opt/1A/toolchain/x86_64-2.6.32-v3-3/bin/g++ test.cpp -o test 11:38PM test.cpp:15:42: error: declaration of ‘operator<<’ as non-function friend std::ostream& operator<< <>(std::ostream&, const TopLevelClass::InnerClass<T>&); ^~ test.cpp:15:42: error: expected ‘;’ at end of member declaration test.cpp:15:45: error: expected unqualified-id before ‘<’ token friend std::ostream& operator<< <>(std::ostream&, const TopLevelClass::InnerClass<T>&); ^ test.cpp: In instantiation of ‘std::ostream& operator<<(std::ostream&, const TopLevelClass::InnerClass<T>&) [with T = int; std::ostream = std::basic_ostream<char>]’: test.cpp:35:17: required from here test.cpp:26:29: error: ‘int TopLevelClass::InnerClass<int>::_x’ is private within this context ioStream << iInnerClass._x << std::endl; ~~~~~~~~~~~~^~ test.cpp:17:17: note: declared private here int _x; ^~ It was my understanding that friend declarations also counted as regular declaration. But here gcc doesn't seems to actually like the friend declaration inside TopLevelClass::InnerClass<T> while gcc <= 5 was fine. Please note that clang doesn't build this either, in any version, unless I uncomment the first two lines. In either cases, it doesn't work with gcc 6. Is this a gcc bug ? Or is this invalid C++ ? Cheers, Romain