C++完美转发

完美转发指的是函数模板可以将自己的参数“完美”地转发给内部调用的其它函数。所谓完美,就是能保证被转发参数的左、右值属性不变。

引入

template<typename T>
void function(T t) {
	otherdef(t);
}

如上所示,function() 函数模板中调用了 otherdef() 函数。完美转发指的是:如果 function() 函数接收到的参数 t 为左值,那么该函数传递给 otherdef() 的参数 t 也是左值;反之如果 function() 函数接收到的参数 t 为右值,那么传递给 otherdef() 函数的参数 t 也必须为右值。
很明显,function并未实现完美转发,无论传递给function的是左值还是右值,最终传递给otherdef的都是左值。

事实上,c++11之前也可以通过重载函数模板来实现完美转

void otherdef(int& t)
{
	cout << "左值" << endl;
}
void otherdef(const int& t)
{
	cout << "右值" << endl;
}

//重载函数模板,分别接收左值和右值
//接收右值参数
template<typename T>
void function(const T& t) 
{
	otherdef(t);
}
//接收左值参数
template<typename T>
void function(T& t)
{
	otherdef(t);
}

int main()
{	
	function(5);
	int x = 1;
	function(x);
	return 0;
}

在这里插入图片描述

完美转发

显然,使用重载的模板函数实现完美转发也是有弊端的,此实现方式仅适用于模板函数仅有少量参数的情况,否则就需要编写大量的重载函数模板,造成代码的冗余。为了方便用户更快速地实现完美转发,C++ 11 标准中允许在函数模板中使用右值引用来实现完美转发。
C++11 标准中规定,通常情况下右值引用形式的参数只能接收右值,不能接收左值。但对于函数模板中使用右值引用语法定义的参数来说,它不再遵守这一规定,既可以接收右值,也可以接收左值(此时的右值引用又被称为“万能引用”)。

仍以 function() 函数为例,在 C++11 标准中实现完美转发,只需要编写如下一个模板函数即可:

template<typename T>
void function(T&& t)
{
	otherdef(t);
}

此模板函数的参数 t 既可以接收左值,也可以接收右值。但仅仅使用右值引用作为函数模板的参数是远远不够的,还有一个问题继续解决,即如果调用 function() 函数时为其传递一个左值引用或者右值引用的实参,如下所示:

	int n = 1;
	int& num = n;
	function(num);

	int&& num2 = 11;
	function(num2);

相应的,T被初始化int&和int&&,而function则变为function(T&&&)和function(T&&&&),c++特意为这种情况指定了新的匹配规则:

funciton(T&&&)========function(T&)
function(T&&&&)=======function(T&&)

还存在一个问题,即无论传入的形参是左值还是右值,对于函数模板内部来说,形参既有名称又能寻址,因此它都是左值。那么如何才能将函数模板接收到的形参连同其左、右值属性,一起传递给被调用的函数呢?

C++11 标准的开发者已经帮我们想好的解决方案,该新标准还引入了一个模板函数 forword(),我们只需要调用该函数,就可以很方便地解决此问题。仍以 function 模板函数为例,如下演示了该函数模板的用法:

void otherdef(int& t)
{
	cout << "左值" << endl;
}
void otherdef(const int& t)
{
	cout << "右值" << endl;
}

template<typename T>
void function(T&& t)
{
	otherdef(forward<T>(t));
}

int main()
{	
	function(5);
	int i = 1;
	function(i);
	return 0;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vegetablesssss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值