Effective Modern C++ 读书笔记(一) 类型推导

本文是Effective Modern C++读书笔记的第一部分,主要探讨类型推导,包括模板类型推导的不同情况:ParamType是普通指针或引用、通用引用、传值以及数组和函数实参的情况。强调了在类型推导过程中,编译器如何处理const、引用和值传递的影响。
摘要由CSDN通过智能技术生成

Deducing Types

模板类型推导
template<typename T>
void f(ParamType param);

编译期间,编译器使用expr进行两个类型推导,一个是针对T,另外一个是针对ParamType的。两个类型通常不同。

因为ParamType通常包括对const和reference的修饰
如:

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

模板类型T的推导不仅仅取决于实参,也取决于ParamType的类型。

下面要分三种情况讨论:

ParamType是指针或者引用,但不是通用引用

规则如下:
如果expr的类型是一个引用,会忽略引用部分

然后剩下的部分决定T,让T与形参决定最终的ParamType

eg:

template<typename T>
void f(T & param);	//param是一个引用
int x=27;		//x是int
const int cx=x;		//cx是const int
const int & rx=cx;	//rx是指向const int的引用

推导结果:

f(x)       // T为int,ParamType为int&
f(cx)      // T为const int,ParamType为const int &
f(rx)      // T为const int,ParamType为const int &

传const int & 参数的时候,会忽略引用语义,模板参数被推导为const int

ParamType是通用reference

如果函数模板为T,通用引用即T&&

  • 如果expr是左值
    T和ParamType会被推导为左值引用
template<typename T>
void f(T&& param);		//param现在是一个通用引用类型
		
int x=27;				//如之前一样
const int cx=x;			//如之前一样
const int & rx=cx;		//如之前一样

f(x)      //T为 int&, param也是
f(cx)     //T为 const int&, param也是
f(rx)     //T为 const int&, param也是

  • 如果expr是右值
    就使用第一条例子
f(27)    // T为 int(忽略引用语义), param为int&&
ParamType是传值
template<typename T>
void f(T param);

无论传递什么东西,param都会成为其一份拷贝——一个新的对象。
类型推导的时候,如果expr是一个引用,忽略这个引用。并且也会忽略const和volatile

int x=27;				//如之前一样
const int cx=x;			//如之前一样
const int & rx=cx;		//如之前一样

f(x);				//T和param都是int
f(cx);				//T和param都是int
f(rx);				//T和param都是int

要牢记,传值给形参的时候,要忽略常量性和易变性。
如:

template<typename T>
void f(T param);		//传值

const char* const ptr = //ptr是一个常量指针,指向常量对象 
" Fun with pointers";
  • 左边的const表示字符串是cosnt
  • 右边的const表示这个char指针是const,即这个ptr不能修改为指向其他地址
    所以实际上param的类型是 const char * , 也就是说指针的自身的常量性将会被忽略。
数组实参
  • 传值
template<typename T>
void f(T param);			

const char name[] = "J. P. Briggs";		//name的类型是const char[13]

f(name);

如果函数的形参是一个数组:

void myFunc(int param[]);

会等价为一个指针形参

void myFunc(int *param);

所以模板参数类型T会被推导为const char *

  • 传引用
template<typename T>
void f(T& param);

如果传的是引用,T会被推导为真正的数组。

函数实参

函数类型也会退化为指针

void someFunc(int, double);	//someFunc是一个函数,类型是void(int,double)

template<typename T>
void f1(T param);		//传值

template<typename T>
void f2(T & param);		//传引用

f1(someFunc);			//param被推导为指向函数的指针,类型是void(*)(int, double)
f2(someFunc);			//param被推导为指向函数的引用,类型为void(&)(int, bouel)
总结

在模板类型推导时,有引用的实参会被视为无引用,他们的引用会被忽略
对于通用引用的推导,左值实参会被特殊对待
对于传值类型推导,实参如果具有常量性和易变性会被忽略

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值