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.

Reply via email to