《Effective Modern C++》条款2:理解auto型别推导

自己之前经常使用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 });

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值