https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93083
Bug ID: 93083 Summary: copy deduction rejected when doing CTAD for NTTP Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: barry.revzin at gmail dot com Target Milestone: --- Reduced a bit from Jonathan Müller's example on Slack: using size_t = decltype(sizeof(0)); template <size_t N> struct string_literal { constexpr string_literal(const char*) {} string_literal(string_literal const&) = default; }; template <size_t N> string_literal(const char (&)[N]) -> string_literal<N - 1>; template <string_literal Str> struct type_string { }; template <string_literal Str> void foo() { type_string<Str>{}; } This does not compile on trunk with: <source>: In function 'void foo()': <source>:17:20: error: class template argument deduction failed: 17 | type_string<Str>{}; | ^ <source>:17:20: error: no matching function for call to 'string_literal(string_literal<...auto...>)' <source>:7:5: note: candidate: 'template<long unsigned int N> string_literal(const string_literal<N>&)-> string_literal<N>' 7 | string_literal(string_literal const&) = default; | ^~~~~~~~~~~~~~ <source>:7:5: note: template argument deduction/substitution failed: <source>:17:20: note: mismatched types 'const string_literal<N>' and 'string_literal<...auto...>' 17 | type_string<Str>{}; | ^ <source>:6:15: note: candidate: 'template<long unsigned int N> string_literal(const char*)-> string_literal<N>' 6 | constexpr string_literal(const char*) {} | ^~~~~~~~~~~~~~ <source>:6:15: note: template argument deduction/substitution failed: <source>:17:20: note: couldn't deduce template parameter 'N' 17 | type_string<Str>{}; | ^ <source>:4:8: note: candidate: 'template<long unsigned int N> string_literal(string_literal<N>)-> string_literal<N>' 4 | struct string_literal | ^~~~~~~~~~~~~~ <source>:4:8: note: template argument deduction/substitution failed: <source>:17:20: note: mismatched types 'string_literal<N>' and 'string_literal<...auto...>' 17 | type_string<Str>{}; | ^ <source>:10:1: note: candidate: 'template<long unsigned int N> string_literal(const char (&)[N])-> string_literal<(N - 1)>' 10 | string_literal(const char (&)[N]) -> string_literal<N - 1>; | ^~~~~~~~~~~~~~ <source>:10:1: note: template argument deduction/substitution failed: <source>:17:20: note: mismatched types 'const char [N]' and 'string_literal<...auto...>' 17 | type_string<Str>{}; | ^ This compiles fine: string_literal s = "hello"; string_literal t = s; So it's only in the NTTP context that this deduction fails to be considered properly.