Effective 型别推导
-
条款1:理解模板型别推导
template<typename T> void f(ParamType param); f(expression);
情况1:ParamType是个指针或引用,但不是个万能引用
- 若expression具有引用型别,则将引用部分忽略
- 然后,对expr的类型与ParamType进行模式匹配,以决定T的类型
- 若ParamType是引用类型也基本同上
情况2:ParamType是个万能引用(&&)
- 如果传入的expression是左值,T和ParamType都会被推导为左值引用
- 如果expression是个右值,则类似情况1进行推导
例如:
void f(T &¶m);//(此处T是模板) int i = 10; f(i); //推导结果⇒ void f(int ¶m)
推导过程:因传入的expression是个左值,所以T被推导为int型左值引用(int &),紧接着(int& &&)被折叠为(int &)
情况3:ParamType既非指针也非引用
- 如果expression具有引用型别,则忽略引用部分
- 忽略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可以完全正确的推导结果