我理解,给定一个支撑的初始化程序,auto
将推导出一种类型std::initializer_list
,而模板类型推导将失败:
auto var = { 1, 2, 3 }; // type deduced as std::initializer_list<int>
template<class T> void f(T parameter);
f({ 1, 2, 3 }); // doesn't compile; type deduction fails
Run Code Online (Sandbox Code Playgroud)
我甚至知道在C++ 11标准中指定的位置:14.8.2.5/5 bullet 5:
[如果程序有,则这是一个非推导的上下文]一个函数参数,其关联参数是初始化列表(8.5.4),但参数没有std :: initializer_list或者可能是cv-qualified std :: initializer_list的引用类型.[ 例如:
模板void g(T);
克({1,2,3}); //错误:没有推断T的参数
- 结束例子 ]
我不知道或不理解的是为什么存在这种类型演绎行为的差异.C++ 14 CD中的规范与C++ 11中的规范相同,因此标准化委员会可能不会将C++ 11行为视为缺陷.
有人知道为什么auto
推导出支撑初始值设定项的类型,但是不允许使用模板吗?虽然对"这可能是原因"形式的推测性解释很有意思,但我对那些知道为什么标准是按原样编写的人的解释特别感兴趣.
c++ templates c++11 list-initialization template-argument-deduction
在他的"C++和Beyond 2012:Universal References"演示中,Scott反复强调了这一点,即通用引用处理/绑定到所有内容,因此重载已经采用通用引用参数的函数是没有意义的.在我混淆之前,我没有理由怀疑这一点std::initializer_list
.
这是一个简短的例子:
#include <iostream>
#include <initializer_list>
using namespace std;
template <typename T>
void foo(T&&) { cout << "universal reference" << endl; }
template <typename T>
void foo(initializer_list<T>) { cout << "initializer list" << endl; }
template <typename T>
void goo(T&&) { cout << "universal reference" << endl; }
template <typename T>
void goo(initializer_list<T> const&) { cout << "initializer list" << endl; }
int main(){
auto il = {4,5,6};
foo( {1,2,3} );
foo( il ); …
Run Code Online (Sandbox Code Playgroud)