自己之前经常使用auto,认为是python下的类型自动推导,但是从来没想过机制是如何的;
auto可以看作另一种模板推导方法,但是由于C++的历史遗留问题,导致过于特殊;
基本形式:
考虑之前条款一所说的模板推导形式;
template<typename T>
void f(ParamType param)
f(exp)
T的类型由ParamType和exp共同决定,从而引出三个条款;
但是auto也不例外;
例如:
const auto& x=3;
可以分开来看:
1.auto看作T;
2.const auto& 可以看作ParamType,即const T&;
3.常数3可以看作exp;
因此,条款1的三条条款可以完美的运用在auto上;
auto ax=x;//可以看作拷贝模板推导,去引用去const;
auto& bx=x;//可以看作引用模板推导,去引用;
auto&& cx=x;//可以看作万能引用推导,左值为引用,右值为右值引用;
特殊例子:
1.大括号初始化问题:
但是这里注意下历史遗留问题,即auto在括号初始化会被优先推导为std::initializer_list形式;
换句话说,auto和模板型别推导的唯一不同便是在这,普通模板型别推导无法识别括号初始化,而auto可以;
auto x={12,13,45};
//会被推导为std:initializer_list<int>;
即对于auto来说,会优先假使大括号的初始化表达式为std::initializer_list,而普通的模板推导不会,因此如果采用大括号初始化,只有auto识别,其他情况下无法识别;
但是这个问题针对于不同版本的C++会有所区别待遇,所以最好不要用大括号初始一般变量;
2.auto规定函数返回值:
在C++14中,auto可以作为函数返回值推导,但是注意,此时会视auto为模板型别推导;
换句话说,想返回大括号序列不会识别为std::initializer_list,因此无法完成模板推导;
auto createInlist() {
return{ 1,2,3 };
}
3.lambda表达式捕获auto:
在C++14中,和auto规定返回值类似,lambda表达式捕获也视为普通模板型别推导,而不是auto型别推导;
vector<int>v;
auto resetV = [&v](const auto& newValue) {v = newValue; };
resetV({ 1,2,3 });