C++引用与模板(forward+move实现完美转发)

一、使用模板,可以实现左值引用和右值引用,当实参可能会左值,也可能为右值时使用引用结合模板。
二、两个重要工具

  1、move:实现移动语义,将左值变为右值。使用语法:move(左值)。
  2、forward:可以保持数据的类型不变,可用于实现完美传参和完美转发。
   2.1、为啥需要forward:因为在C++函数调用时,实参变量都会变为左值,而实参本身可能不是左值,这就导致实参失去了原来的数据类型。

实参变量:左值变量,左值引用类型变量,右值引用类型变量,都有内存实体,能取地址;
非变量:右值,没有内存实体,在寄存器里,不能取地址。

   2.2、完美转发:模板将自身的形参作为其他函数的实参时,保持模板形参的数据类型不变,不让模板的形参在作为其他函数的实参时全部变为左值。即实参类型为左值或左值引用时就传递左值或左值引用,实参类型为右值引用或右值时就传递右值或右值引用。

#include<iostream>
using namespace std;

void display(int& val) { cout << "& call" << endl; }
void display(int&& val) { cout << "&& call" << endl; }
void display(const int& val) { cout << "cons& call" << endl; }
void display(const int&& val) { cout << "const&& call" << endl; }

//引用+模板
template<typename T> 
void func(T&& t) {
	//display(t); //t变为左值,只会调用形参为int&
	display(forward<T>(t)); //forward实现完美转发
}

void testLeft() {
	int a(10);
	cout << "左值推理:";
	func(a);
	int& ra(a);
	cout << "左值引用推理:";
	func(forward<int&>(ra));

	const int b(200);
	cout << "const左值推理:";
	func(b);
	const int& rb(b);
	cout << "const左值引用推理:";
	func(forward<const int&>(rb));
}

void testRight() {
	cout << "右值推理:";
	func(10000); //不是变量,实参不会变为左值
	cout << "右值引用推理:";
	int&& rr(1000000);
	//forward<变量原有类型> (变量名)
	func(forward<int&&>(rr)); //保持数据类型为int&&,而不变为int 

	const int a(1);
	cout << "const 右值引用推理:";
	//move(左值):将左值变为右值
	const int&& rra(move(a));
	func(forward<const int&&>(rra));
}
int main() {
	testLeft();
	cout << "--------华丽的分割线-----------" << endl;
	testRight();

	return 0;
}

在这里插入图片描述

三、推理规则:
/*
设左值类型为A,左值引用类型A&,右值引用类型A&&
1.传入左值A时:模板 T -> A& ,形参类型 t -> A&
2.传入左值引用A&时:模板 T -> A& ,形参类型 t -> A&
3.传入右值时:模板 T -> A, 形参类型 t -> A&&
4.传入右值引用A&&时:模板 T -> A, 形参类型 t -> A&&
*/
四、规律总结
/*
结论:
1.左值和左值引用做实参时,模板里的T为左值引用类型,形参类型T&&也为左值引用类型
2.右值和右值引用做实参时,模板里的T为左值类型,形参类型T&&为右值引用类型
*/
四、forward图示补充

在这里插入图片描述
 由上图知,不使用forward来保持参数的原有数据类型就会和左值调用一样。
在这里插入图片描述
 使用forward之后,实参就保持了原有的数据类型不变,实现完美传参。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值