https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87652
--- Comment #1 from Ryan R Haining <haining.cpp at gmail dot com> --- ugh, very sorry, I copied the version with private: instead of protected. The example program should be: template <typename> struct Outer { template <typename> class Inner { template <typename> friend class Inner; // All Inners should be friends public: template <typename T> void use_other_x(const Inner<T>& other) const { (void)other.x; } protected: // no error if private instead int x; }; }; int main() { Outer<int>::Inner<void> i1; Outer<int>::Inner<char> i2; i1.use_other_x(i2); }