https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884
Bug ID: 108884 Summary: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope? Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: zyn7109 at gmail dot com Target Milestone: --- Clang implements deferred concept instantiation in [D126907](https://reviews.llvm.org/D126907). As that patch suggests, according to [temp.friend]/9, > A friend function template with a constraint that depends on a > template parameter from an enclosing template shall be a definition. > Such a constrained friend function or function template declaration > does not declare the same function or function template as a > declaration in any other scope. That being said, such code should not compile as constrained friend declaration (#1) doesn't declare the function defined out of class scope (#2). (Example comes from https://github.com/clangd/clangd/issues/1511) ```cpp // https://gcc.godbolt.org/z/sP9xdTqhe template <typename> concept C = true; template <C... Ts> class Foo { private: Foo(const Ts&...) {}; public: friend auto factory(const C auto&...); // #1 }; auto factory(const C auto&... ts) // #2 { return Foo{ts...}; } int main() { factory(5); } ``` Such code is rejected in Clang 16 onwards, showing that function defined at #2 is trying to access private constructor of `Foo`, but GCC still accepts this, which implies GCC considers #1 and #2 are the same function. Is this a GCC regression or I have missed something from the wording? Note that if we swap #1 and #2, i.e., ```cpp // https://gcc.godbolt.org/z/WfG7vnxx8 template <typename> concept C = true; template <C... Ts> class Foo { private: Foo(const Ts&...) {} public: friend auto factory(const C auto&... ts) { return Foo{ts...}; } }; template <C... Ts> auto factory(const C auto&... ts) -> Foo<Ts...>; int main() { factory(5); } ``` then both GCC and Clang would accept it.