http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59930
Bug ID: 59930 Summary: template friend declarations, namespaces, and explicit instantiations don't mix Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: luto at mit dot edu namespace NS { template<typename T> class Holder { private: void func(); template<typename> friend class User; }; template class Holder<long>; template<typename T> class User { public: void method() const { Holder<T> x; x.func(); } }; } // namespace // This one is okay, oddly. // template class NS::Holder<long>; void Foo() { NS::User<long> decl; decl.method(); } says (in trunk r207012): $ g++-trunk -Wall -c template_friend.cc template_friend.cc: In instantiation of ‘void NS::User<T>::method() const [with T = long int]’: template_friend.cc:34:14: required from here template_friend.cc:7:7: error: ‘void NS::Holder<T>::func() [with T = long int]’ is private void func(); ^ template_friend.cc:22:3: error: within this context x.func(); ^ The 4.8 branch can't compile this either, but clang is okay with it. Oddly, removing the namespace, removing the explicit instantiation, or moving the explicit instantiation outside the namespace causes g++ to accept this code.