【发布时间】:2015-02-06 17:04:29
【问题描述】:
初始化器列表表达式对于初始化 C++ 容器非常方便:
std::vector<int>({1, 2, 3})
...但似乎大括号括起来的初始化列表表达式,如{1,2,3} 将仅绑定到采用std::initializer_list<int> 的函数 - 它不会 似乎绑定到一个通用(转发)引用:
template <class T>
void foo(T&& v)
{
std::vector<int>(std::forward<T>(v));
}
int main()
{
foo({1, 2, 3})
}
这个输出:
test2.cpp:11:6: note: template<class U> void foo(U&&)
test2.cpp:11:6: note: template argument deduction/substitution failed:
test2.cpp:33:13: note: couldn't deduce template parameter ‘U’
(这是 GCC 4.7.2 的结果。)
不幸的是,这意味着我们无法转发初始化列表表达式。既然这样做会很方便,我想问为什么这不起作用?为什么大括号括起来的初始化列表表达式不能绑定到转发引用?或者这是允许的,也许我的编译器太旧了?
【问题讨论】:
-
转发
initializer_list是没有用的:它已经有引用语义,并且它的元素是const,因此不可移动。 -
它们是否可移动并不重要 - 通用转发引用不一定意味着移动,它只是意味着按原样沿参数转发
-
是的,但是花括号初始化列表没有类型。因此,您不能“按原样”转发它。
-
括号初始化列表不是表达式。因此它没有类型。这一事实造成了无穷无尽的混乱。
标签: c++ templates c++11 initializer-list