Contents
模板类型推导
条款1:理解模板类型推导
模板及调用的一般形式:
情况1:ParamType是个指针或引用,但不是个万能引用
推导规则:
1.若expr具有引用类型,先将引用部分忽略。
2.尔后,对expr的类型和ParamType的类型进行模式匹配,来决定T的类型。
例如,有如下的模式:
|
|
在第二个和第三个调用语句中,由于cx和rx的值都被指明为const,所以T的类型被推导为const int,从而形参param的类型就成了const int&。
上述调用语句示例演示的都是左值引用形参,但是右值引用形参的类型推导方式是完全相同的。
若将形参类型从T&改为const T&,结果和意想中的差别不大。cx和rx的常量性仍得到满足,但由于现在假定param具有const引用类型,T的类型推导结果中没有必要再包含const了。推导如下:
若param是个指针(或指向const对象的指针)时,推导方式本质上一样:
情况2:ParamType是个万能引用
- 若expr是个左值,T和ParamType都会被推导为左值引用。这个结果有两重神奇之处:首先,这是在模板类型推导中,T被推导为引用类型的唯一情形。其次,尽管在声明时使用的是右值引用语法(T&&),它的型别推导确实左值引用。
- 若expr是个右值,则应用“常规”(情形1中的)规则。
例如: ```cpp template void f(T&& param) //param现在是个万能引用
int x = 27; //同前 const int cx = x; //同前 const int& rx = x; //同前
f(x); //x是左值,所以T的类型是int&,param也是 f(cx); //cx是左值,所以T是const int&,param也是 f(rx); //rx是左值,所以T是const int&,param也是 f(27); //27是右值,所以T是int,这样一来,param:int&&
情况3:ParamType既非指针也非引用(即按值传递)
这意味着无论传入什么,param都会是它的一个副本,即一个全新的对象。这也决定了此时的推导规则:
- 一如之前,若expr具有引用类型,则忽略引用属性。
- 忽略expr的引用性之后,若expr是const或者volatile对象,也忽略之。
也即实参的&,cv属性影响不了形参param