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

文章目录

  • 1.转发
  • 2.完美转发
  • 3.std::forward和std::move的区别
  • 4.参考资料

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

1.转发

#include 
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;
}

【深入理解C++】转发、完美转发、std::forward_第1张图片

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

#include 
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;
}

【深入理解C++】转发、完美转发、std::forward_第2张图片

2.完美转发

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

#include 
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;
}

【深入理解C++】转发、完美转发、std::forward_第3张图片

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

#include 
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;
}

输出结果如下:

【深入理解C++】转发、完美转发、std::forward_第4张图片

#include 
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;
}

输出结果如下:

【深入理解C++】转发、完美转发、std::forward_第5张图片

4.参考资料

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

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

你可能感兴趣的:(深入理解C++,c++,完美转发,forward)