《Effective Modern C++》学习总结(条款1- 5)

本文详细介绍了C++中的模板类型推导,包括非通用引用、通用引用和非引用参数的情况,以及数组和函数参数的推导规则。强调了理解和使用`auto`关键字的重要性,同时提及其潜在的缺点和陷阱。
摘要由CSDN通过智能技术生成

第一章、类型推导

 

条款1:理解模板类型推导

模板类型推导的核心就在于模板参数的类型(也就是下文中的ParamType)和传入对象类型,下面将其分为三种情况分析。

第一种情况:ParamType是个非通用的引用或者是一个指针

1.当传递一个const对象给一个引用参数时,往往会期望对象保留其const特性,也就是说,参数变成了const的引用
  • 这也是为什么给一个以T&为参数的模板传递一个const对象是安全的——对象的const特性是模板参数类型推导的一部分
template<typename T>
void f(T& param);						//	param是一个引用类型

int	x = 27;								//	x是一个int
const int cx = x;						//	cx是一个const	int 
const int& rx =	x;						//	rx是const	int的引用

f(x);									//	T是int,param的类型时int& 
f(cx);									//	T是const	int,
										//	param的类型是const	int& 
f(rx);									//	T是const	int
										//	param的类型时const	int&
2.如果传递一个普通对象给一个const T&模板参数,那么同样,编译器会自动为传递来的对象添加const特性
template<typename T>
void f(const T& param);					//	param现在是const的引用 
int	x =	27;									//	和之前一样
const int cx = x;							//	和之前一样 
const int& rx =	x;							//	和之前一样
f(x);										//	T是int,param的类型是const int&  
f(cx);										//	T是int,param的类型是const int& 
f(rx);										//	T是int,param的类型是const int&
3.在上述的两类传递参数过程中,引用特性(或指针)在类型推导的过程中会被忽略(可以理解为引用只是传递参数的一种手段,与模板内部的参数类型无关)
template<typename T>
void f(T* param);							//	param是一个指针 
int	x =	27;									//	和之前一样
const int *px =	&x;							//	px是一个指向const	int	x的指针 

f(&x);										//	T是int, param的类型是int* 
f(px);										//	T是const int  
											//	param的类型时const int*

第二种情况:ParamType是个通用的引用(Universal Reference)

右值引用(也就是函数模板使用一个类型参数T ,一个通用的引用参数的申明类型是T&&

4.使用了通用的引用,左值参数和右值参数的类型推导大不相同,举例如下:
template<typename T>
void f(T&& param);							//	param现在是一个通用的引用 
int	x =	27;									//	和之前一样
const int cx = x;							//	和之前一样 
const int& rx =	x;							//	和之前一样
f(x);										//	x是左值,所以T是int& 
											//	param的类型也是int&
f(cx);										//	cx是左值,所以T是const int& 
											//	param的类型也是const int&
f(rx);										//	rx是左值,所以T是const int& 
											//	param的类型也是const int&
f(27);										//	27是右值,所以T是int 
											//	所以param的类型是int&&

第三种情况:ParamType既不是指针也不是引用

5.当ParamType既不是指针也不是引用,我们把它处理成pass-by-value:
template<typename T>
void f(T param);							//	param现在是pass-by-value

int	x =	27;									//和之前一样 
const int cx = x;							//和之前一样 
const int& rx =	x;							//和之前一样
f(x);										//T和param的类型都是int 
f(cx);										//T和param的类型也都是int 
f(rx);										//T和param的类型还都是int
  • 注意此处cxrx都是const类型,但ParamType却不是const,这是因为传入的不是cxrx本身(或其引用),而是它们的拷贝版本,cxrx不能被修改和param能不能被修改是没有关系的。这也就是expr的常量特性在推导param的过程中被忽略掉了(expr不能被修改并不意味着它的一份拷贝不能被修改)
6.考虑到expr是一个const的指针指向一个const对象,而且expr被通过pass-by-value传递给param
template<typename T>
void f(T param);							//param仍然是按值传递的(pass-by-value) 
const char*	const ptr =						
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值