您的位置:首页 > 编程语言 > C语言/C++

C++ auto类型推导

2017-07-15 20:43 525 查看
关于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 = int
const auto cx = x; //T = auto->int ,ParmaType = const int


编译器进行auto类型推导是就好像存在一个模版函数调用,对其T、ParamType进行推导(除了一个例外)

同样也是类似模版类型推导分为三类来进行推导。只不过是根据type specifier来划分。

初始化推导例外

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


//初始化一个初值为27的变量,采用auto
auto x1 = 27;
auto x2(27);
//对于c++11
auto 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_list

template<typename T>
void f(T param);
f({1, 2, 3}) //错误,模版类型推导不可推导出T = int

//解决办法
template<typename T>
void f(std::initialzer_list<T> param); //正确,T=int
f({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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: