《Effective Modern C++》学习笔记之条款二:理解auto型别推导

首先我们需要明确的是auto型别推导与模板型别推导的运作原理几乎完全相同,如下所见:

auto x = 27;           // x型别为int
const auto cx = x;     // cx型别为const int
const auto& rx = x;    // rx型别为const int&
auto&& uref1 = x;      // x为int,且为左值,所以uref1类型为int&
auto&& uref2 = cx;     // cx为const int,为左值,所以uref2类型为const int&
auto&& uref3 = 27;     // 27为int,且为右值,所以uref3 类型为int&&

const char name[] = "this is test"; // name型别为const char[13]
auto arr1 = name;                   // arr1型别为const char*
auto& arr2 = name;                  // name型别为const char(&)[13]

void somefunc(int,double);  // somefunc是一个函数,型别为 void(int,double)
auto func1 = somefunc;      // func1类型为void(*)(int,double)
auto& func1 = somefunc;     // func2类型为void(&)(int,double)

我们知道,C++11为了支持统一初始化,增加了大括号初始化表达式:

auto x1 = {27};  // x1为含有单个值27的std::initializer_list<int>类型变量
auto x2{27};     // 同上

由上面代码可以看出,对于大括号初始化表达式,auto会将其推导为一个std::initializer_list<T>的类型,而模板型别推导则无法完成此类推导,从而失败。

auto x = {27,11,2,9};  // x被推导为std::initializer_list<int>类型

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

f({27,11,2,9}); // 错误,无法推导出T的类型

请注意,虽然模板推导识别不了大括号初始化表达式类型,但若你指定该模板中的param为std::initializer_list<T>类型,则,此时再传入大括号初始化表达式,就可以正常识别出T的类型了:

template<typename T>
void f(std::initializer_list<T> param);

f({27,11,2,9}); // 此时,T被推导为int,param为std::initializer_list<int>

 最后,我们还应该知道,在C++14中,允许使用auto来说明函数返回值需要推导,而且C++14中的lambda表达式的形参声明中也可以使用auto进行修饰。但是需要注意的时,这些场景下的auto用法使用的时模板型别推导,而非auto型别推导。

所以,带有auto返回值的函数若要返回一个大括号括起来的初始化表达式,是通不过编译的:

auto func() {
  return {1, 2, 3}; // 编译报错,无法完成{1, 2, 3}的型别推导
}

同理,使用auto来指定C++14中的lambda表达式形参型别时,也不能使用大括号括起来的初始化表达式来做实参:

std::vector<int> v;
auto resetV = [&v](const auto& new_value) {v = new_value};

resetV({1,2,3}); // 错误,无法完成{1,2,3}型别推导
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chiang木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值