Sil*_*ler 11 c++ templates initializer-list c++11
初始化列表表达式非常便于初始化C++容器:
std::vector<int>({1, 2, 3})
Run Code Online (Sandbox Code Playgroud)
......但似乎一个括号内的初始化列表表达式,如{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})
}
Run Code Online (Sandbox Code Playgroud)
这输出:
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’
Run Code Online (Sandbox Code Playgroud)
(这是GCC 4.7.2的结果.)
遗憾的是,这意味着我们无法转发初始化列表表达式.既然这样做很方便,我想问为什么这不起作用?为什么括号封闭的初始化列表表达式不能绑定到转发引用?或者这是允许的,也许我的编译器太老了?
Dra*_*rax 15
并不是它不能绑定到你的函数的参数; 只是编译器无法检测模板的类型.这编译:
#include <vector>
template <class T>
void foo(T&& v)
{
std::vector<int>(std::forward<T>(v));
}
int main()
{
foo(std::initializer_list<int>{1, 2, 3});
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下无法推导出初始化列表。这实际上由 [temp.deduct.call] 中的标准明确涵盖:
模板参数推导是通过将每个函数模板参数类型 (call it
P
) 与调用 (call itA
)的相应参数类型进行比较来完成的,如下所述。如果P
是依赖类型,[...]。否则,初始值设定项列表参数会导致参数被视为非推导上下文 (14.8.2.5)。[ 例子:Run Code Online (Sandbox Code Playgroud)template<class T> void f(std::initializer_list<T>); f({1,2,3}); // T deduced to int f({1,"asdf"}); // error: T deduced to both int and const char* template<class T> void g(T); g({1,2,3}); // error: no argument deduced for T
这里的示例g
正是您的情况 -T
不是依赖类型,因此这被认为是非推导的上下文。编译器拒绝您的代码是正确的。
归档时间: |
|
查看次数: |
3456 次 |
最近记录: |