Effective mordern c++ --- 类型推导

扎实的理解模板、auto、decltype三种类型推导十分必要,本文介绍模板参数推导

1.理解模板参数类型推导

首先定义模板参数类型推导的定义

template<typename T>
void f(ParamType param)
当我们调用f(expr)时,我们可以从expr同时推导出T和ParamType两种类型,这里的ParamType跟T可以不同,比如 ParamType 可以为 const T&等类型。根据Param的类型,我们推导的规则分三种情况:

a、ParamType是一个指针或者引用类型,但不是universal reference(具体定义后面博客会描述,接近但区别于右值引用)

这里的推导规则:

(1)如果expr是一个引用,忽略引用的部分(就是说T是不带有引用特性的)

(2)根据ParamType类型匹配exptr来推导T.(个人理解是paramtype去掉引用后的类型就是expr去掉引用的类型,再根据paramtype的类型推导T)

举个例子:

template<typename T>
void f(T& param); //这里ParamType是一个引用类型(T&)
int x = 27;  //x为int类型
const int cx = x; //cx 是一个常量类型
const int &rx = x;//rx是一个常量引用

f(x); //T是int型,paramtype 是 int&
f(cx);//T是const int,paramtype 是 const int&
f(rx);//同上
按照以上的推导规则,这里的后面两次调用T都是const int,这也说明当一个模板以引用或指针的形式定义时,const的属性是保留的. 其中最后一次调用,忽略了re的引用,T依旧为一个 const int值。

当我们把参数由T&变成 const T&时,情况有所改变。这里cx和rx的类型const属性依旧是保留的,但是由于paramtype是一个const&,所以没有必要再将T推导为const类型。

template<typename T>
void f(const T& param); //这里ParamType是一个引用类型(T&)
int x = 27;  //x为int类型
const int cx = x; //cx 是一个常量类型
const int &rx = x;//rx是一个常量引用

f(x); //T是int型,paramtype 是 const int&
f(cx);//T是int,paramtype 是 const int&
f(rx);//同上,T的引用类型依旧是忽略的

同样对于指针来说,也具备相同的规则:

template<typename T>
void f(T* param);  //现在paramtype是一个指针
int x = 27;
const int* px = &x;
f(&x);    //T是int,paramtype是int*
f(px);   //T是const int ,paramtype 是const int*


b.Paramtype 是一种universal reference

这里的推导规则:

(1)如果expr是一个左值,T和ParamType都会被推导为左值引用,这里的情况很特殊,因为这是唯一一种T被推导为引用的情况;另外尽管ParamType在表达上是一个右值引用,实际上确实一个左值引用。

(2)如果expr是一个右值,推导规则按照第一种情况

举例说明:

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

int x = 27;
const int cx = x;
const int& rx = x;
f(x);   //x是一个左值,所以T是int& paramtype 也是 int&
f(cx);  //cx是一个左值,所以T是const int&,paramtype 是 const int&
f(rx);  //rx是一个左值,所以T是一个const int&,paramtype 是 const int&
f(27);  //27是一个右值,所以T就是一个int paratype是一个int&&


c.Paramtype 既不是一个指针和引用

显然,这种情况下Paramtype是传值调用,传值说明param是一个拷贝啊,所以推导规则:

(1).如果expr是一个引用类型,忽略引用的部分

(2)忽略传进来的const \volatile属性   

void templalte<typename T>f(T param)  
int x = 27;  
const int cx = x;  
const int &rx = x;  
f(x);  
f(cx); f(rx); //这里所有的调用都是T和param都是int 
template<typename T>    
void f(T param);  
const char* const ptr = "fun"; //ptr是一个执行const 对象的const 指针  
f(ptr);  //这里T和param的是什么类型呢  
这里ptr有两个const,第一个表示指针指向的一个const类型,第二个表示ptr是一个const指针。这里传递值时ptr是一个拷贝,指针的数值传给他,但本身的const属性会被忽略,因此这里肯定是一个 const char* 类型啊。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值