C++11引入自动类型推导,首先在源代码中自动类型相当于占位符,编译器在编译阶段根据上下文关系推导出实际的类型,并根据实际的类型进行编译。
auto:
根据auto定义时,实际的右边类型进行编译。大大简化编程工作,并且由于编译期确定,不会带来运行期负担。
int main() { map<string,int> mp; mp["str1"]=1; mp["str2"]=3; //传统遍历map方式 需要书写冗长的类型 for(map<string,int>::iterator it=mp.begin();it!=mp.end();it++) { cout<<it->first<<" "<<it->second<<endl; } cout<<"use auto"<<endl; //采取auto类型自动推导 for(auto it=mp.begin();it!=mp.end();it++) { cout<<it->first<<" "<<it->second<<endl; } }执行结果一致:
auto类型推导在搭配增强for循环时,配合在容器类中使用,将更为简洁方便:
int main() { map<string,int> mp; mp["str1"]=1; mp["str2"]=3; cout<<"use auto+for"<<endl; //采取auto类型+ 增强for 循环 for(auto it:mp) { cout<<it.first<<" "<<it.second<<endl; } }
结果一致:
可用在返回值:
auto fun(int i) { return i; } int main() { auto j=fun(1); cout<<j<<endl; }可用在类类型:
class A { public: int val; }; int main() { A a; auto c=a; cout<<c.val<<endl; }用在函数参数?:
C++11并未作规定,
如果编译器能确定auto实际类型
调用处语法通过,那么将可以通过编译。调用处语法不通过,那么无法通过编译。通过编译:
auto fun(auto l) { l+=l; return l; } int main() { auto c=fun(10); cout<<c<<endl; }输出:
编译不通过:
auto fun(auto l) { l+=l; return l; } int main() { auto c=fun("12"); cout<<c<<endl; }
由此可见:
对于参数含有auto类型的,编译器会作警告,单独编译能够通过。但被其它部分调用处,编译可能不通过,取决于实际类型的语法。因此函数参数最好不要设置为auto类型。auto类型相当于编译器的语法糖,会在调用处展开为具体类型。
语法糖:为了增加可读性与方便编程,编译器对语法糖作展开,与不使用语法糖编译后代码完全一致。
decltype
可以根据推导出的类型用于定义。
推导出mp类型,并用此类型进行新的定义
int main() { map<string,int> mp; decltype(mp) _mp; _mp["str"]=1; _mp["stc"]=2; }
分析其与auto使用差别可以发现
auto通常用于接受一个自动类型赋值。decltype则用于根据推导出的类型,进行新的定义。自动类型推导是编译期的语法糖,并不会带来运行期开销。