使用rvalue initializer_list进行类型推断

a.l*_*ram 11 c++ c++11

在以下代码中

#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;
}
Run Code Online (Sandbox Code Playgroud)

rvalue initializer_list可以推导,auto但不能推断template.

为什么C++会禁止这个?

Ker*_* SB 9

我相信这是由于14.8.2.1/1:

[...]初始化列表参数使参数被视为非推导的上下文(14.8.2.5).[ 例如: [...]

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

- 结束例子 ]

现在您可能认为这auto只是模板参数推导,但对于支撑列表auto在7.1.6.4/6 中得到特殊处理:

auto新发明的类型模板参数U 替换出现,或者如果初始化器是braced-init-list(8.5.4),则用std::initializer_list<U>.[...] [ 示例:

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

- 结束例子 ]