c++新特性-模板的类型推导

在进入正题之前,我们先来看看什么时顶层const(high-level const)和底层const(low-level const)

简单点说,顶层const修饰的是数据类型本身,底层const不是.

举例:

const int i = 0;//顶层const,因为作用在int上
const int* p1 = &i;//底层const,因为作用在int上,而不是int*

int a = 0;
int* const p2 = &a;//顶层const,因为作用的是int*
const int& s = a;//底层const,因为作用的是int,而不是int&
  

现在进入正题

一般来说我们看到的函数模板都是下面的这个形式

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

f(expr);

/*
    其中paramType代表含T的表达式,比如:T,T*,T&
    param就是变量名
    expr就是实参
*/

现在第一种情况:ParamType既不是指针也不是引用

规则:     

        1.如果expr是引用,那么引用将会被忽略,如(int& 退化为 int)。

        2.执行上一步后,如果expr中有顶层const,那么顶层const将会被忽略,如(const int 退化为 int)。

        3.执行前两步之后,expr类型会和ParamType比较,取并集。得到就是ParamType的类型,T的类型就是在ParamType中去掉修饰的部分,如(ParamTypel:T*,那么去掉*,剩下的就是T的类型)。注意:ParamType的类型会被先推导出来,然后才是T的类型。

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

int x = 1;
const int cx = x;
int& rx = x;
const int& crx = x;
int* px = &x;
const int* const cpxc = &x;

f(x);//T为int,param的类型为int

f(cx);//T为int,param的类型为int

f(rx);//T为int,param的类型为int

f(crx);//T为int,因为&会先去掉变成了const int,此时const是顶层const,param的类型为int

f(px);//T为int*,param的类型为int*

f(cpxc);//T为const int*,param的类型为const int*

第二种情况 :ParamType是指针

规则:

        1.如果expr是引用,那么引用将会被忽略,如(int& 退化为 int)。

        2.执行上一步后,如果expr中有顶层const,那么顶层const将会被忽略,如(const int 退化为 int)。

        3.执行前两步之后,expr类型会和ParamType比较,取并集。得到就是ParamType的类型,T的类型就是在ParamType中去掉修饰的部分,如(ParamTypel:T*,那么去掉*,剩下的就是T的类型)。注意:ParamType的类型会被先推导出来,然后才是T的类型。

 

template<typename T>
void f(T* param);

int x = 0;
const int cx = x;
int& rx = x;
const int& crx = x;
int* px = &x;
const int* const cpxc = &x;

f(&x); T为int,param的类型为int*

f(&cx);//T为const int,param的类型为const int*
/*
    &cx相当于const int*类型,与T*并集为,const int*
    所以ParamType为const int*,又因为ParamType是T*,
    所以T为const int
*/


f(&rx);//T为int,param的类型为int*

f(&crx);//T为const int,param的类型为const int*

f(px);//T为int,param的类型为int*

f(cpxc);//T为const int,param的类型为const int*

第三种情况:ParamType是一个引用

规则:

        1.如果expr是引用,那么引用将会被忽略,如(int& 退化为 int)。

        2.执行前一步之后,expr类型会和ParamType比较,取并集。得到就是ParamType的类型,T的类型就是在ParamType中去掉修饰的部分,如(ParamTypel:T*,那么去掉*,剩下的就是T的类型)。注意:ParamType的类型会被先推导出来,然后才是T的类型。

这种情况最为简单,它不需要你用规则去推导就能一眼看出来,就像它引用的意义一样,ParamType的类型就是:去掉引用的expr的类型+&。那么T就是去掉引用的expr的类型。

template<typename T>
void f(T& param);

int x = 0;
const int cx = x;
int& rx = x;
const int& crx = x;
int* px = &x;
const int* const cpxc = &x;

f(x); T为int,param的类型为int&

f(cx);//T为const int,param的类型为const int&


f(rx);//T为int,param的类型为int&

f(crx);//T为const int,param的类型为const int&

f(px);//T为int*,param的类型为int*&

f(cpxc);//T为const int* const,param的类型为const int* const&

第四种情况:ParamType是个通用引用

规则:

        1.expr是一个左值,执行第三种情况的规则,有点区别那就是T与ParamType的类型一样,都是引用。

        2.expr是一个右值,执行第一种情况的规则。

template<typename T>
void f(T&& param);

int x = 0;
const int cx = x;
int& rx = x;
const int& crx = x;
int* px = &x;
const int* const cpxc = &x;

f(x);//T为int&,param的类型为int&

f(cx);//T为const int&,param的类型为const int&


f(rx);//T为int&,param的类型为int&

f(crx);//T为const int&,param的类型为const int&

f(px);//T为int*&,param的类型为int*&

f(cpxc);//T为const int* const&,param的类型为const int* const&

f(27);//T为int,param的类型为int&&

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值