https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120758

            Bug ID: 120758
           Summary: Empty initializer list (`{}`) incorrectly deduces an
                    array size for array reference parameter
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mital at mitalashok dot co.uk
  Target Milestone: ---

Compiling the following with `-std=c++11 -fsyntax-only`
<https://godbolt.org/z/PoGsqTdqr>:

    template<__SIZE_TYPE__ N, typename T>
    void f(T(&)[N], T(&)[N]);

    int main() {
        const int arr[2] = {};
        f<2>(arr, {});  // Compiles
        f(arr, {});  // Fails
    }

Results in the following error:

/tmp/test.cpp: In function 'int main()':
/tmp/test.cpp:7:6: error: no matching function for call to 'f(const int [2],
<brace-enclosed initializer list>)'
    7 |     f(arr, {});  // Fails
      |     ~^~~~~~~~~
/tmp/test.cpp:7:6: note: there is 1 candidate
/tmp/test.cpp:2:6: note: candidate 1: 'template<long unsigned int N, class T>
void f(T (&)[N], T (&)[N])'
    2 | void f(T(&)[N], T(&)[N]);
      |      ^
/tmp/test.cpp:2:6: note: template argument deduction/substitution failed:

There are no more notes. Expected behaviour is that the two function calls
result in calling `f<2, const int>`, or if this is the intended behaviour, for
a note about why the template argument deduction/substitution failed.

The reason I believe this to be valid is because
<https://wg21.link/temp.deduct.call>:

> If removing references and cv-qualifiers from P gives 
> std::initializer_list<P′> or P′[N] for some P′ and N and the argument is a 
> non-empty initializer list, [...] Otherwise, an initializer list argument 
> causes the parameter to be considered a non-deduced context.

And `{}` is not non-empty, so it should not affect deduction.

Reply via email to