【Effective Modern C++】第二章 auto:5. 优先使用 auto,而非显式类型声明

传统显示类型声明存在的问题

1. 忘记初始化产生未知行为

但是,auto声明的变量其类型推导自其初始化表达式,所以它们必须初始化:

c++ 复制代码
int x1; // 有潜在的未初始化风险 
auto x2; // 编译错误!必须有初始化表达式
auto x3 = 0; // 没问题, x 已经定义了

2. 类型冗长复杂,难以直接写出

在泛型编程、容器操作等场景中,尝尝会出现冗长复杂的类型声明。如:typename std::iterator_traits<It>::value_type,可以直接使用auto代替。

c++ 复制代码
// 传统显式声明:冗长繁琐,易出错 typename 
std::vector<int>::const_iterator it1 = vec.cbegin(); 

// auto 声明:简洁高效,无需记忆复杂类型 
auto it2 = vec.cbegin();

3. 类型不匹配导致意外的类型转换。

std::function是C++11标准库中的一个模板,它把函数指针的思想加以推广。函数指针只能指向函数,而std::function却可以指向任何可调用对象,即任何可以像函数一样实施调用之物。可以处理C++中的闭包类型。

但是,闭包类型只有编译器自己知道,显式声明闭包类型可能产生潜在的类型转换。如:

c++ 复制代码
std::unordered_map<std::string, int> m; 

// 看似合理,实则存在类型不匹配
for (const std::pair<std::string, int>& p: m) {
	... // 在p上实施某些操作
}

哈希表中的 std::pair (也就是 std::unordered_map 本身)的类型并不是 std::pair<std::string, int> ,而是 std:: pair<const std::string, int>

还可以避免一种被称作者为"类型捷径"的问题。如:

c++ 复制代码
std::vector<int> v; 
unsigned sz = v.size();

在 32 位 Windows 上, unsignedstd:: vector<int>::size_type 的尺寸是一样的,但在 64 位 Windows 上, unsigned 是 32 位,而 std:: vector<int>::size_type 则是 64 位。

其他优势

  • auto存储所需的内存可能比std::function更小,且调用效率更高(std::function采用类型擦除技术,存在间接调用开销,auto直接推导闭包原始类型,无额外损耗)。
  • 方便进行统一修改和重构,变量类型会随初始化表达式自动适配,修改源头类型时,无需手动调整所有相关变量,减少遗漏风险。
  • 支持匿名类型的直接使用,C++中的lambda表达式、匿名类均为编译器生成的匿名类型,无法手动显式声明,auto是唯一能直接存储这类对象的方式。

可能存在的问题:无法一眼看出对象的类型,但是IDE的对象类型显示能力能缓和这个问题,而且良好的命名比类型更能表达意图。

总结

  • auto变量必须初始化,基本上对会导致兼容性和效率问题的类型不匹配现象免疫,还可以简化重构流程,通常也比显式指定类型要少打一些字。
  • auto类型的变量都有着2. 理解 auto 类型推导和6中所描述的毛病。

原著在线阅读地址

相关推荐
BestOrNothing_20158 小时前
C++零基础到工程实战(4.3.3):vector数组访问与遍历
c++·迭代器·stl·vector·动态数组
charlie1145141918 小时前
通用GUI编程技术——图形渲染实战(三十三)——Direct2D与Win32/GDI互操作:渐进迁移实战
c++·图形渲染·gui·win32
文祐9 小时前
C++类之虚函数表及其内存布局(一个子类继承一个父类)
开发语言·c++
墨尘笔尖10 小时前
最大最小值降采样算法的优化
c++·算法
YIN_尹12 小时前
【Linux系统编程】进程地址空间
linux·c++
EverestVIP12 小时前
C++中空类通常大小为1的原理
c++
网域小星球13 小时前
C++ 从 0 入门(六)|C++ 面试必知:运算符重载、异常处理、动态内存进阶(终极补充)
开发语言·c++·面试
晚会者荣13 小时前
红黑树的插入(有图)
c++
John.Lewis13 小时前
C++进阶(12)附加学习:STL之空间配置器(了解)
开发语言·c++·笔记
汉克老师13 小时前
GESP2023年12月认证C++三级( 第三部分编程题(2、单位转换))
c++·string·单位转换·gesp三级·gesp3级