• 条款1:理解模板型别推导

    template<typename T>
    
    void f(ParamType param);
    
    f(expression);
    

    情况1:ParamType是个指针或引用,但不是个万能引用

    1. 若expression具有引用型别,则将引用部分忽略
    2. 然后,对expr的类型与ParamType进行模式匹配,以决定T的类型
    3. 若ParamType是引用类型也基本同上

    情况2:ParamType是个万能引用(&&)

    1. 如果传入的expression是左值,T和ParamType都会被推导为左值引用
    2. 如果expression是个右值,则类似情况1进行推导

    例如:

    void f(T &&param);//(此处T是模板)
    int i = 10;
    f(i);  //推导结果⇒ void f(int &param)
    

    推导过程:因传入的expression是个左值,所以T被推导为int型左值引用(int &),紧接着(int& &&)被折叠为(int &)

    情况3:ParamType既非指针也非引用

    1. 如果expression具有引用型别,则忽略引用部分
    2. 忽略const以及volatile修饰

    数组实参

    数组以及函数型别的实参会退化为相应的指针,除非被用来初始化引用

  • 条款2:理解auto型别推导

    • auto推导和模板型别推导基本一致,其唯一的区别在于auto会假定大括号括起来的初始化表达式代表一个std::initializer_list,但模板型别推导不会
    • 但如果模板中的参数类型为std::initializer_list,则模板推导机制会推导出T应有的型别
    • 在函数返回值或lambda式形参中使用auto将会使用模板型别推导而非auto型别推导
  • 条款3:理解decltype

    • 大多数情况下,decltype会得出变量或表达式的型别而不做任何修改
    • 因为在C++的定义中,表达式(x)也是一个左值,所以对于型别为T的左值表达式,除非该表达式仅有一个名字,decltype总是得出型别T&,假设x是一个T型左值,decltype(x)推导出的类型是T而decltype((x))推导出的类型是T&
    • C++14支持decltype(auto),表示使用decltype的推导规则进行推导
  • 条款4:掌握查看类别推导结果的方法

    • 使用boots的typeindex::type_id_with_cvr可以完全正确的推导结果