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;
}

右值可以用但不能用initializer_list推导。autotemplate

为什么 C++ 禁止这样做?

4

1 回答 1

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

结束示例]

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

用新发明的类型模板参数 U替换出现,auto或者,如果初始值设定项是花括号初始化列表(8.5.4),则用std::initializer_list<U>. [...] [示例

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

结束示例]

于 2013-07-05T20:27:21.277 回答