在以下代码中
#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++会禁止这个?
我相信这是由于14.8.2.1/1:
[...]初始化列表参数使参数被视为非推导的上下文(14.8.2.5).[ 例如: [...]
Run Code Online (Sandbox Code Playgroud)template<class T> void g(T); g({1,2,3}); // error: no argument deduced for T- 结束例子 ]
现在您可能认为这auto只是模板参数推导,但对于支撑列表auto在7.1.6.4/6 中得到特殊处理:
用
auto新发明的类型模板参数U 替换出现,或者如果初始化器是braced-init-list(8.5.4),则用std::initializer_list<U>.[...] [ 示例:Run Code Online (Sandbox Code Playgroud)auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>- 结束例子 ]