【现代C++】类型推导与auto

(点击上方公众号,可快速关注)

类型推导(Type inference 或 Type deduction),顾名思义就是编译器能自动推导出数据类型,免去了显式的类型声明。Java、C#等静态语言都支持该特性,C++也在C++11标准开始支持。

:在C++中,一般将类型推导称为Type deduction,其他语言不少称之为Type inference,虽然名字不太一样,但指的是一回事。

类型推导与模板也能结合使用,比较复杂且不常用,这里仅介绍最常用的用法。

语法

C++11并没有专门引入新的关键字,重载了现有的auto关键字,用来告知编译器要类型推导。语法很简单:

[const] [volatile] auto[&|&&] v = expr;

其中,cv和引用都是可选的。编译器根据expr的推导结果决定变量v的类型。

用途

最基本也最常用的用法是减少类型名的长度。由于C++引入了类、命名空间等作用域,要限定其中某个类型可能需要多个作用域符号,导致类型名比较长,不利于编码。一般用auto解决这类情况。

比如,你要声明某个容器类型的迭代器,需要敲这么多字符

std::vector<int> exam;
std::vector<int>::const_iterator it = exam.cbegin();

可以简化为:

auto it = exam.cbegin();

特别说明:C++里的类型推导都是在编译阶段进行的,不影响生成的可执行文件的效率。

注意点

  • C++里的类型推导能力有限,只能根据初始化值的类型推断对应变量的类型

std::vector<int> exam;
auto it; // error,编译器没法知道it的类型,因为没有初始化的值作为推导的依据
it = exam.cbegin();
int64_t add(int64_t lhs, int64_t rhs);

auto i = 5; // i为int类型,因为整型字面量值默认int类型
auto j = 6;    // 同上
auto k = add(i, j); // i和j自动提升为int64_t类型,k为int64_t类型

从上能看出来,C++里的类型推导相对简单,只能根据右边的初始化值的类型推导左边的变量的类型,如果没有右边的表达式没法推导左边的变量类型。这区别于某些编程语言,如Haskell,能根据变量的使用方式推导出变量的类型。还拿上例来说,相应的Haskell代码:

add :: Int64 -> Int64 -> Int64;

let i = 5  -- i为Int64类型,因为字面值5是多态的,
           -- 由于在add中作为Int64类型使用,推导出i为Int64类型
let j = 6  -- 同上
let k = add(i, j); -- k为Int64类型
  • auto推导出的结果是decayed,即

  • 会把右边的constvolatile限定符丢掉

  • 会将引用类型转为被引用的类型,即,推导出的变量不是引用类型

  • 同时还会将原始数组以及函数转为相应的指针类型

    要多加注意第二点,因为涉及到复制操作,可能影响效率。

    std::vector<int> vLarge; //很大的容器
    auto vLarge1 = vLarge; // 复制一份给vLarge1
    auto& vLarge1 = vLarge; // vLarge1为引用类型
  • 在语法一节里只说了一种初始化方式:=,C++有4种初始化方式,非常复杂,有些情况可能比较意外,如下例:

auto i {10};  //等价于于auto i = 10;
auto j = {10}; //j为std::initializer_list<int>

这个时候可使用typeid获取类型。C++不一致的规则非常多,不用熟记这么多脑裂的规则。

喜欢我的文章,请关注我的公众号。转载请标明出处。

af0699305949149ec59ff12eb32b9d3e.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值