《Hello C++》3.8 auto 自动类型推导

《Hello C++》3.8 auto 自动类型推导
0x3ff18a你还记得吗?我们曾在 3.1 简单变量及类型和 3.3浮点类型中介绍了大量的变量类型。事实上通过后续学习你会发现还有更多更复杂的类型等着你去学习,甚至你还会认识到较为特殊的匿名类型。这一些列类型组成了 C++ 庞大且复杂的类型系统,而面对类型日益复杂化带来的编码负担,C++ 11 引入了 auto 类型推导,这一举措既提升了代码的编写效率和安全性又提升了代码的可维护性。
在 C++ 11 之前的版本中,定义变量或者声明变量之前都必须指明它的类型,但在 C++ 11 中,编译器可以自主去介入推导类型了,这就使得 C++ 的代码编写更加方便和安全。在之前的 C++ 版本中,auto 关键字用来存储类型说明符,显式声明变量的存储期,这其实相当冗余鸡肋。因为局部变量[1]默认就是自动存储期,显式添加 auto(auto int a) 与直接写 int a 本质上没有任何区别。由于是默认行为,显式声明就显得有点多此一举了。
而 C++11 移除了 auto 关键字自动存储期的含义,并赋予 auto 关键字新的作用 —— 自动类型推导。也就是说,使用了 auto 关键字以后,编译器会在编译期间自动推导出变量的类型,这样我们就不需要手动指明变量的数据类型了。下面是一个简单的示例:
1 | auto a = 20; // a 是 int 类型 |
- 第 1 行中:20 是一个整数,默认是 int 类型,所以推导出来的变量 a 类型是 int 型;
- 第 2 行中:20.25 是一个小数,默认是 double 类型,所以推导出来的变量 b 类型是 double 型;
- 第 3 行中:1.9L 是一个小数,后缀 L 表示 long double 类型,所以推导出来的变量 c 类型是 long double 型;
- 第 4 行中:“https://blog.yujiay.wang/” 是一个字符串字面量,在 C++ 中类型是 const char*[2],所以推导出来的变量 d 类型是 const char* 型;
介绍到这里,肯定有同学想了,auto 太棒了,不需要在人为再去记忆那么多复杂的类型了,一个 auto 不就可以搞定一切了吗?错的同学错的。自动类型推导并不是为了这种简单情况而设计的,让你心寒了。事实上,如果将其用于这种简单的情况,反而可能得不偿失。例如,你需要将某一人的身高(单位为厘米)存为 double 类型,以便后续程序中与米制单位进行转换,你使用了如下代码:
1 | auto height = 183; |
程序将直接将 height 变量推导成 int 类型的 183,而不是我们期待的 double 183.0 。显式的声明类型时,将变量初始化为 double 183 不会造成任何问题,但自动类型推导可能会造成难以排查大问题便得不偿失。
auto 只有在处理复杂类型时,比如用来定义标准模板库(STL)中的迭代器时(标准模板库及迭代器会在第十四章进行详细介绍,这里只是为了演示 auto 关键字的正确使用时机,不必死磕代码),需要使用迭代器遍历容器中的元素,不同容器的迭代器有不同的类型,在定义迭代器时必须要指明。而迭代器的类型有时候比较复杂,书写起来也很麻烦,我们便可以借助自动类型推导进行简化。
1 |
|
不难发现,定义迭代器 i 时,类型写起来很长,而且还容易出错,但是借助 auto 自动类型推导,我们可以进行重写,让其更简洁:
1 |
|
这里我们需要注意,使用 auto 自动类型推导的变量必须马上初始化。这点很容易解释,因为 auto 关键字只是“占位符”,并非如 int、double 等关键字是真正的类型声明。
通过以上学习,相信你已经掌握了 auto 自动类型推导,在后续的学习过程中,我们会带领大家通过 auto 关键字优化我们的程序。




