• 条款5:优先使用auto,而非显示型别声明

    • auto可以用来表示编译器才掌握的类别

      因此可以用auto声明/存储一个闭包变量,且内存量也和该闭包一样,而使用std::function声明的、存储的一个闭包变量是std::function的一个示例,所以不管给定签名如何,它都占有固定尺寸的内存而这个尺寸对于其存储的闭包而言不一定够用,若是如此,std::function的构造函数就会分配堆上的内存来存储该闭包,且编译器的实现细节一般会限制内联,并会产生间接的函数调用,所以std::function来调用闭包几乎必然比起使用“auto”手法来得又大又慢!

    • 显示声明可能导致你既不想要也没想到的隐式型别转换

    • auto变量必须初始化,基本上对会导致兼容性和效率问题的型别不匹配的现象免疫

  • 条款6:当auto推导的型别不符合要求时,使用带显式型别的初始化物习惯用法

    • 有的时候,auto的推导结果与程序员所要的结果完全不同,例如下列代码

      std::vector<bool> foo() 
      {
      	std::vector<bool> r;
      	//...
      	return r;
      }
      
      //k的值取决于std::vector<bool>::reference的实现
      auto k = foo()[0]; //k的型别被推断为std::vector<bool>::reference而不是bool
      //有一种实现让对象含有一个指针,指涉到一个机器字,该机器字有那个被引用的比特,再加上基于那个比特对应的字的偏移量
      //foo()返回一个临时对象,在“auto k = foo()[0];”此表达式完成后此对象将被析构,此时k将含有一个空悬指针,使用k将造成未定义结果
      
    • 因为std::vector做过特化,用了一种压缩形式表示持有的bool元素,每个bool元素用一个比特来表示,但这种做法给operator[]带来了一个问题,因为按理来说std::vector的operator[]应该返回一个T&,然而C++中禁止比特引用,所以就需要使用std::vector::reference型别代理

    • std::vector::reference是个代理类的实例,所谓代理类,就是为了模拟增广其他型别的类。代理类的用途广泛。比如说,std::vector::reference就是为了制造std::vector的operator[]返回了一个比特的引用假象。再比如说,标准库中的智能指针也是代理类,它们是为了将资源管理嫁接到裸指针之上

    • 总之,隐形的代理类和auto无法和平共处,所以上面的代码应使用显式型别初始化

      auto k = static_cast<bool>(foo()[0]);//正确写法