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

            Bug ID: 93164
           Summary: variadic template function passed an initializer list
                    fails with argument count mismatch error rather than
                    expected "couldn't deduce template parameter" error
           Product: gcc
           Version: 9.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: davidfink314 at gmail dot com
  Target Milestone: ---

foo({x});
An initializer list passed to a template function can be a non-deduced context,
which can result in template argument deduction failing.

https://stackoverflow.com/questions/52924740/stdinitializer-list-braced-initialization-and-header


When this is a regular template argument, the error message is OK (mentions
template deduction failed with the template parameter name).

When this is a variadic template argument, errors about the number of arguments
are thrown instead, which are wrong and don't help the user correct their code.


Use gcc 9.2 -std=c++17 -Wall -Werror on godbolt, with the code below:


#include <initializer_list>

struct X {
    template <class... Args>
    X(Args&&... args) {
    }
    template<class... Args>
    X& operator=(Args&&... args) {
        return *this;
    }
};

template<class... T> void variadic(T&&...) {}

template<class T> void single(T&&) {}

int main() {
    X x;

    // Expected error: no matching function for call to ... couldn't deduce
variadic template parameter 'T'
    // Actual error: 'X& X::operator=()' must have exactly one argument
    x = {0};

    // Expected error: no matching function for call to ... couldn't deduce
variadic template parameter 'T'
    // Actual error: too many arguments to function 'void variadic(T&& ...)
[with T = {}]'
    variadic({0});

    // Good error: error: no matching function for call to
'single(<brace-enclosed initializer list>)
    //             ... couldn't deduce template parameter 'T'
    single({0});

    return 0;
}

Reply via email to