1.理解模板类型推断

1. Understand template type deduction

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

f(expr); 

在编译时刻,编译器使用expr的类型去推断出两种类型
①是T
②是ParamType
注意 模板类型和参数类型通常是不一致的 参数类型经常有些修饰

template<typename T>
void f(const T& param); // ParamType is const T&
int x = 0;
f(x);

T被推断出是int,而ParamType 被推断出 const int&
/**********************************************************/
通常情况下 T与所传入的实参类型是相同的 但不能一概而论

分为三种情况

情况1:ParamType是一个指针或引用,但不是一个万能引用(通用引用)。
若expr具有引用型别,先将引用部分忽略。
而后,对expr的型别和ParamType的型别执行模式匹配,来决定T的型别。  
 
情况2:ParamType是一个万能引用
如果expr是一个左值,T和ParamType都会被推导为左值引用。
如果expr是一个右值,则应用“常规”(即情况1中的)规则

情况3:ParamType既非指针也非引用
若expr具有引用型别,则忽略其引用部分。
忽略expr的引用性后,若expr是个const对象,也忽略之。
若其是一个volatile对象,也忽略之。

2.对情况1进行说明

引用部分会被忽略,而且是根据参数类型来推导的

	template <typename T>
	void Fun(T& a)
	{
	  
	}

     int nNum1 = 10;
     const int nNum2 = 20;
     const int& nNum3 = nNum2;

     Fun(nNum1);  	//T int
     Fun(nNum2);	//T const int
     Fun(nNum3);	//T const int

我们在main函数中 对其进行测试, 在VS中进行debug查看数据类型
①第一个Fun(int ) a是类型是(int &)
②第二个Fun(const int) a是类型是(const int &)
②第三个Fun(const int&) a是类型还是是(const int &)
这就是为什么传递一个const对象 给一个带有T&的形参是安全的

//***********************************************//

template<typename T>
void f(const T& param); // param is now a ref-to-const

int x = 27; 
const int cx = x; 
const int& rx = x; 

f(x); // T is int, param's type is const int&
f(cx); // T is int, param's type is const int&
f(rx); // T is int, param's type is const int&

template <typename T>
void Fun(T * a)
{
    
}
     const int* p = &nNum1;
     const int* & pr = p;

     Fun(p);
     Fun(pr);

T的类型都是const int

3.对情况2进行说明

在这里插入图片描述

template<typename T>
void f(T&& param); // 形参现在是一个通用引用

int x = 27; 
const int cx = x;
const int& rx = x; 

f(x); // x is lvalue, so T is int&,
 // param's type is also int&
 
f(cx); // cx is lvalue, so T is const int&,
 // param's type is also const int&
 
f(rx); // rx is lvalue, so T is const int&,
 // param's type is also const int&
 
f(27); // 27 is rvalue, so T is int,
 // param's type is therefore int&&

4.对情况3进行说明

template<typename T>
void f(T param); // param is now passed by value

int x = 27; 
const int cx = x;
const int& rx = x; 

f(x); // T's and param's types are both int
f(cx); // T's and param's types are again both int
f(rx); // T's and param's types are still both int

我们可以看到 const 和 引用的部分都被忽略了,因为是pass by value 所以形参是一个副本,跟原来的实参没有关系。

template<typename T>
void f(T param); // param is still passed by value

const char* const ptr = // ptr is const pointer to const object
 "Fun with pointers";
 
f(ptr); // pass arg of type const char * const

param will be const char*

左边的const修饰字符串,右边的const修饰指针ptr,在传给f的时候,ptr的修饰被拿掉了 所以是const char *

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值