Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

type inference with rvalue initializer_list

Tags:

c++

c++11

In the following code

#include <initializer_list>
#include <utility>

template<typename T> void f(T&& x) {}
template<typename T> void g(std::initializer_list<T> x) {}

int main()
{
    auto   x = {0}; // OK
    auto&& y = {0}; // OK
    g(x); // OK
    g(std::move(x)); // OK
    g({0}); // OK
    f(x); // OK
    f(std::move(x)); // OK
    f({0}); // failure
    return 0;
}

rvalue initializer_list can be deduced with auto but not with template.

Why C++ forbids this?

like image 994
a.lasram Avatar asked Jul 05 '13 20:07

a.lasram


1 Answers

I believe this is due to 14.8.2.1/1:

[...] an initializer list argument causes the parameter to be considered a non-deduced context (14.8.2.5). [Example: [...]

template<class T> void g(T);
g({1,2,3});                    // error: no argument deduced for T

end example]

Now you may think that auto is just template argument deduction, but for braced lists auto receives special treatment in 7.1.6.4/6:

replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list (8.5.4), with std::initializer_list<U>. [...] [Example:

auto x1 = { 1, 2 };   // decltype(x1) is std::initializer_list<int>

end example]

like image 131
Kerrek SB Avatar answered Sep 29 '22 23:09

Kerrek SB