第四章是无用的,这里暂时不整理了。

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

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

int x1;  //有潜在的未初始化风险,编译器最多给告警
auto x2; //未初始化,编译报错

2、可以使用auto来表示只有编译器才知道的型别,例如lambda表达式。而且还简化了代码

// 如果用std::function来接收,则myfunc 的类型为 
std::function<bool(const std::unique_ptr<Widget>& p1,const std::unique_ptr<Widget>& p2)> 很啰嗦,很复杂不是吗
// 相对于std::function,无论从效率还是代码整洁度方面,auto都是完胜
auto myfunc = [](const std::unique_ptr<Widget>& p1,const std::unique_ptr<Widget>& p2) {    
    return *p1 < *p2;
}


3、在跨系统代码迁移时,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,将可以完全规避这个问题。