【深入理解C++】转发、完美转发、std::forward

前置知识:万能引用、引用折叠

1.转发

#include <iostream>
using namespace std;

template <typename F, typename T, typename Q>
void FuncTemplate(F f, T&& t, Q&& q)    // 函数模板,万能引用
{
	// f是要转发的目标函数
	// 20是右值,T为int类型,t为int&&类型
	// i是左值,Q为int&类型,q为int&类型
	f(t, q);
}

void myfunc(int x, int& y)
{
	x += 10;
	y += 10;
	cout << "x = " << x << ", y = " << y << endl;
	return;
}

int main()
{
	int i = 100;
	FuncTemplate(myfunc, 20, i);
	cout << "i = " << i << endl;

	return 0;
}

在这里插入图片描述

上面代码中的函数模板可以实现 myfunc(int x, int& y) 的转发,但是不能完成 myfunc(int&& x, int& y) 的转发,这是因为 t 虽然是 int&& 类型,但 t 本身是个左值,不能被右值引用 x 接收。

#include <iostream>
using namespace std;

template <typename F, typename T, typename Q>
void FuncTemplate(F f, T&& t, Q&& q)    // 函数模板,万能引用
{
	// f是要转发的目标函数
	// 20是右值,T为int类型,t为int&&类型,但t本身是个左值,不能被右值引用x接收
	// i是左值,Q为int&类型,q为int&类型
	f(t, q);
}

void myfunc(int&& x, int& y)
{
	x += 10;
	y += 10;
	cout << "x = " << x << ", y = " << y << endl;
	return;
}

int main()
{
	int i = 100;
	FuncTemplate(myfunc, 20, i);
	cout << "i = " << i << endl;

	return 0;
}

在这里插入图片描述

2.完美转发

在上面代码中,经历了函数模版参数 t 这一次转发,右值的属性被改变为了左值,为了解决上述问题,这时就需要完美转发了。

#include <iostream>
using namespace std;

template <typename F, typename T, typename Q>
void FuncTemplate(F f, T&& t, Q&& q)    // 函数模板,万能引用
{
	// f是要转发的目标函数
	// 20是右值,T为int类型,t为int&&类型,但t本身是个左值,不能被右值引用x接收
	// i是左值,Q为int&类型,q为int&类型

	f(std::forward<T>(t), q); // forward实现完美转发
}

void myfunc(int&& x, int& y)
{
	x += 10;
	y += 10;
	cout << "x = " << x << ", y = " << y << endl;
	return;
}

int main()
{
	int i = 100;
	FuncTemplate(myfunc, 20, i);
	cout << "i = " << i << endl;

	return 0;
}

在这里插入图片描述

3.std::forward和std::move的区别

#include <iostream>
using namespace std;

void print(int& t) // 形参的类型是左值引用
{
	cout << "print(int& t)" << endl;
}

void print(int&& t) // 形参的类型是右值引用
{
	cout << "print(int&& t)" << endl;
}

template <typename T>
void FuncTemplate(T&& t)    // 函数模板,万能引用
{
	// 20是右值,T为int类型,t为int&&类型,但t本身是个左值,不能被右值引用接收
	print(t);
	print(std::forward<T>(t));
	print(std::move(t));
}

int main()
{
	FuncTemplate(20);

	return 0;
}

输出结果如下:

在这里插入图片描述

#include <iostream>
using namespace std;

void print(int& t) // 形参的类型是左值引用
{
	cout << "print(int& t)" << endl;
}

void print(int&& t) // 形参的类型是右值引用
{
	cout << "print(int&& t)" << endl;
}

template <typename T>
void FuncTemplate(T&& t)    // 函数模板,万能引用
{
	// i是左值,T为int&类型,t为int&类型
	print(t);
	print(std::forward<T>(t));
	print(std::move(t));
}

int main()
{
	int i = 100;
	FuncTemplate(i);

	return 0;
}

输出结果如下:

在这里插入图片描述

4.参考资料

https://www.cnblogs.com/refantasy/p/10026080.html

https://cloud.tencent.com/developer/article/1561681

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值