https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82478
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- Reduced: struct true_type { static const bool value = true; }; struct false_type { static const bool value = false; }; template <typename T> using void_t = void; template <typename, typename = void> struct HasPrivate { static const bool value = false; }; template <typename T> struct HasPrivate<T, void_t<typename T::PRIVATE>> { static const bool value = true; }; class A { struct PRIVATE { }; // Either should be sufficient. friend struct HasPrivate<A>; template <typename, typename> friend struct HasPrivate; }; static_assert(HasPrivate<A>::value, ""); Clang compiles this, but GCC and EDG don't. GCC says: priv.cc:23:15: error: ‘struct A::PRIVATE’ is private within this context static_assert(HasPrivate<A>::value, ""); ^~~~~~~~~~~~~ priv.cc:16:12: note: declared private here struct PRIVATE { }; ^~~~~~~ EDG says: "priv.cc", line 23: error: static assertion failed with "" static_assert(HasPrivate<A>::value, ""); ^ 1 error detected in the compilation of "priv.cc". I don't know what the standard says about the effect of friendship on template argument lists in a partial specialization.