C++ auto类型推导

来源:互联网 发布:怎么学好数据库 编辑:程序博客网 时间:2024/04/29 21:49

关于auto的语法auto specifier
之前看过EffectiveModernC++的 模版类型推导部分,下面总结一下auto类型推导的规则。


推导原则
如果看过了模版类型推导其实auto类型推导是几乎完全一致的。在这二者之间存在一个直接映射的关系。
在模版类型推导中使用以下原型解释

template<typename T>void f(ParamType param);f(expr);

当使用auto来声明变量时,auto相当于上述T,auto的一些装饰符(const、volatile、&等)与T组合(type specifier)成了ParamType。

auto x = 27; //T = auto -> int, ParamType = auto = intconst auto cx = x; //T = auto->int ,ParmaType = const int

编译器进行auto类型推导是就好像存在一个模版函数调用,对其T、ParamType进行推导(除了一个例外)
同样也是类似模版类型推导分为三类来进行推导。只不过是根据type specifier来划分。


初始化推导例外

//初始化一个初值为27的变量,直接声明类型int x1 = 27;int x2(27);//对于c++11int x3 = {27};int x4{27};
//初始化一个初值为27的变量,采用autoauto x1 = 27;auto x2(27);//对于c++11auto x3 = {27};auto x4{27};

以上代码前两个即是声明初始化了27的变量,而后两个却是声明并初始化了std::initializer_list<int>。当使用auto声明的变量采用{}来初始化时,推导的类型为std::initializer_list<T>


auto 类型推导对比模版类型推导例外

//使用initializer_list来调用函数模版不能推导成功auto x = {1, 2, 3}; // auto->initializer_listtemplate<typename T>void f(T param);f({1, 2, 3}) //错误,模版类型推导不可推导出T = int//解决办法template<typename T>void f(std::initialzer_list<T> param); //正确,T=intf({1, 2, 3}) 

可见,auto类型推导和模版类型推导真正的区别是:auto类型推导将{}初始化方法看作initializer_list类型,但模版类型推导却不这样做。这个陷阱导致非必要情况下不要使用{}初始化。


在C++14中
1.允许使用auto来说明函数返回类型需要类型推导。但是,使用的推导的方式为模版类型推导。

auto function(){    return {1, 2, 3};//错误,模版类型推导不支持initializer_list}

2.在lambda表达式中,允许对参数使用auto。但是同样使用的是模版类型推导策略。

auto my_lambda = [](const auto& t){};my_lambda({1, 2, 3}); //错误,模版类型推导不支持initializer_list
原创粉丝点击