https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116640
Bug ID: 116640 Summary: Inconsistent compiler rules when using private types as default template parameters Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: joshua.maiche at gmail dot com Target Milestone: --- Created attachment 59071 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59071&action=edit main source file (Also tested on godbolt trunk) Version: gcc version 14.0.1 20240412 (experimental) [master r14-9935-g67e1433a94f] System: Ubuntu 24.04 LTS Command: gcc main.cpp Source: --- struct Outer { private: struct PrivateStruct; public: template <typename = PrivateStruct> struct Inner1 {}; template <typename SelfType = Outer, typename = typename SelfType::PrivateStruct> struct Inner2 {}; }; Outer::Inner1<> obj1{}; // Compiles fine. Outer::Inner2<> obj2{}; // Fails to compile due to private access. --- Output: --- main.cpp:13:8: error: ‘struct Outer::PrivateStruct’ is private within this context 13 | Outer::Inner2<> obj2{}; // Fails to compile due to private access. | ^~~~~~~~ main.cpp:3:12: note: declared private here 3 | struct PrivateStruct; | ^~~~~~~~~~~~~ --- The C++ compiler seems to have inconsistent rules when using private types in a member function template. I could see why private types would be accepted as default template parameters, since they're being declared in a member of a struct, so that could have access to privates. I could also see why private types would be rejected as default template parameters, since they're being evaluated at the point where the template is being called, which could be considered "outside the struct" However, it seems inconsistent to have it where private types are accepted as default parameters (Inner1), but not as a default parameter dependent on a previous parameter (Inner2). For comparison, Clang and MSVC accept both Inner1 and Inner2.