《Effective Modern C++》学习笔记之条款五:优先选用auto,而非显示型别声明

废话补多少,直接总结一下使用auto的好处:

1、对于变量未初始化情况,如果使用显示显示型别声明,程序猿将无感知,但是如果使用了auto进行变量声明,将提醒你编译错误。

int x1;  //有潜在的未初始化风险
auto x2; //未初始化,编译报错

2、简化代码,特别时迭代器相关的,能够省略很大的代码量

3、对于某些lambda表达式,我们应使用auto变量来接收它,而非std::function,因为无论从效率还是代码整洁度方面,auto都是完胜

//应使用auto而非std::function
auto dereflens = [](const auto& p1,const auto& p2) { return *p1 > *p2}

4、在跨系统代码迁移时,auto有着更好的健壮性。例如STL的vector容器的size()函数返回值类型实际上是std::vector<int>::size_type,可能大部分人都不知道这个类型,在写代码时,我们也仅仅用unsigned来接受该函数返回值。但是我们需要知道在32位操作系统中,unsigned和std::vector<int>::size_type都是32位,所以可以直接这样接收,但是在64位操作系统中std::vector<int>::size_type是64位,此时如果还用unsigned(32位)来接收,将会越界。如果我们使用auto进行声明,无论是32位还是64位,sz都和std::vector<int>::size_type一样大小

//当前是32位
std::vector<int>
unsigned sz = v.size() //此时sz与std::vector<int>::size_type的大小都为32位


//当前是64位
std::vector<int>
unsigned sz = v.size() //此时sz是32位,std::vector<int>::size_type是64位,越界


但是如果我们使用auto,可以直接移植,无需关心

5、对于一些隐晦知识点,可以起到很好的规避作用。例如如果以下代码没有使用auto将会导致一个很隐秘的问题:

std::unordered_map<std::string,int> m;

for(const std::pair<std::string,int>& p :m) {
   ...//一些操作
}

上面的代码忽略了一个事实,那就是std::unordered_map的键值部分是const,所以其成员类型是std::pair<const std::string,int>而非std::pair<std::string,int>,所以上述代码将会发生std::pair<const std::string,int> -> std::pair<std::string,int>的隐式类型转换,由const转换为非const的方法就是进行复制操作,生成临时变量,然后把p绑定到这个临时变量上,而且在一次循环结束,这个临时变量也将会被析构。分析可以看出,上面的代码,非常浪费效率。但是如果我们使用auto,将可以完全规避这个问题。

要点速记

  • auto变量必须初始化,基本上对会导致兼容性和效率问题的型别不匹配现象免疫,还可以简化重构流程,通常会比显示指定类型少打一些字
  • auto型别有着条款2和条款6所描述的缺点

猜你喜欢

转载自blog.csdn.net/Chiang2018/article/details/114005645