Luna's blog 月亮月亮酱

完美转发

2019-07-28
C++

右值作为函数参数的场景

#include <iostream>

using std::cout;
using std::endl;

template<typename T>
void func(T& param)
{
	cout << "传入的是左值" << endl;
}
template<typename T>
void func(T&& param)
{
	cout << "传入的是右值" << endl;
}


template<typename T>
void warp(T&& param) 
{
	func(param);
}


int main() 
{
	int num = 2019;
	warp(num);
	warp(2019);
	return 0;
}

这段代码输出的结果是左值、左值。

在main函数中分别向warp函数传递了一个左值和右值,参数匹配没有问题,但是因为形参具有名字从而使传进去的右值变为了左值,导致参数再进行传递时匹配到了左值的func。

完美转发

那么如何让形参能正确的匹配到右值参数呢?

查看warp的参数匹配结果,分别匹配成了int #int##也就是说,模板中的 T 保存着传递进来的实参的信息,我们可以利用 T 的信息来强制类型转换我们的 param 使它和实参的类型一致。

如果我们可以将其强制转换回右值,就能匹配到右值的函数啦。类似这样

template<typename T>
T&& forward(T &param)
{
	return static_cast<T&&>(param);
}

这样当传入的值是右值时,可以返回右值,当传入值是左值时会返回左值,这样就实现了完美转发。

这里涉及到引用折叠,后面会更详细的学习引用折叠的问题。

代码如下;

template<typename T>
void warp(T&& param)
{
	func(std::forward<T>(param));
}

Similar Posts

Content