Modern Effective C++:item 1 理解模板类型推导

通用引用(万能引用)

通用引用通常表示为 T&&,其中 T 是一个模板参数类型(模板中的&&表示通用引用)。&& 虽然通常表示一个右值引用,但当T由模板参数推导而来时,其既可以绑定左值,又可以绑定右值。当 T 是一个模板参数类型,并且T是推导出来的类型,T&&才是通用引用。

万能引用 既可以接收左值,又可以接收右值。实参是左值,通用引用就是左值引用(引用折叠)实参是右值,通用引用就是右值引用。

(引用折叠 :当其传入参数为左值时,&&会折叠成&;当传入参数为右值时,&&不折叠照常接收)

void Fun(int& x){cout<<"左值引用"<< endl; }
void Fun(const int& x){cout<<"const左值引用"<< endl; }
void Fun(int&& x) {cout<<"右值引用"<<endl; }
void Fun(const int&& x) {cout<<"const右值引用"<< endl; }
// 万能引用:既可以接收左值,又可以接收右值
// 实参左值,他就是左值引用(引用折叠)
// 实参右值,他就是右值引用
template<typename T>
void PerfectForward(T&& t){
    Fun(t);
}
int main(){
 PerfectForward(10); // 右值
 int a;
 PerfectForward(a);     
 return 0;
}

(2)模板类型推导

理解auto的模板类型推导如果你不介意浏览少许伪代码,可以考虑像这样一个函数模板:

template<typename T>
voidf(ParamType param);

它的调用看起来像这样

f(expr);                        //使用表达式调用f

编译期间,编译器使用expr进行两个类型推导:一个是针对T的,另一个是针对ParamType。这两个类型通常不同,因为ParamType包含一些修饰,如const和引用修饰符。

对于模板函数:

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

编译器需要完成两步类型推导:

1)推导 T 的类型

T是模板参数,当调用 f 函数并传递一个参数时,编译器会尝试根据该参数来确定 T 的具体类型。

如果调用 f(10),编译器会推断 T 是 int。

(2)推导 ParamType 的类型

ParamType 是函数参数的类型,它可以是 T 本身,也可以是对 T 进行了一些修饰后的类型,比如加上 const、&(引用)、*(指针)等。例如,假设定义如下函数模板

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

ParamType 是 const T&,T 的常量引用。如果调用 f(10),编译器会推断 T 是 int,ParamType 是 const int&。

template<typename T>
void f(const T& param) {
    // 函数体
}

调用示例1

int x = 10;
f(x);

编译器推导 T 为 int,ParamType 为 const int&。

调用示例 2

double y = 3.14;
f(y);

编译器推导 T 为 double,ParamType 为 c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值