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.