条款2:理解auto类型推导
条款1中,模板类型推导的函数模板形如:
template<typename T>
void f(ParamType param);
当变量采用auto声明时,auto扮演了模板中的T这个角色,而变量的类型扮演的是ParamType的角色。
条款1中的三种情况同样也适用于auto,只有下面的一点不同。
当用于auto声明变量的初始化表达式是使用大括号括起时,推导所得的类型就属于std::initializer_list。但是,如果向对应的模板传入一个同样的初始化表达式,类型推导就会失败。
auto x = {11, 23, 9}; // x的类型是std::initializer_listtemplate<typename T>
void f(T param);f({11, 23, 9}); // error,无法推导T的类型
所以,auto和模板类型推导真正的唯一区别在于,auto会假定用大括号括起的初始化表达式代表一个std::initializer_list,但模板类型推导却不会。
只有将param声明为std::initializer_list<T>,模板类型推导机制会推导出T应有的类型。
template<typename T>
void f(std::initializer_list<T> initList);f({11, 23, 9}); // T的类型为int
C++14中,允许使用auto来说明函数返回值需要推导,lambda表达式中也会在形参声明中用到auto。然而,这些auto用法是在使用模板类型推导而非auto类型推导。
auto createInitList()
{return {1, 2, 3}; // 错误,无法为{1, 2, 3}完成类型推导
}
