C++:函数重载和模板函数之间的问题 | 完美转发的概念

本文探讨了C++11中的右值引用和函数重载的概念,指出在模板函数中如何正确地调用重载函数。通过示例展示了由于右值引用的特性导致的问题,并解释了完美转发(Perfect Forwarding)的解决方案,利用`std::forward`来保持参数原本的左值或右值特性,确保函数调用的准确性。
摘要由CSDN通过智能技术生成

前言

在之前的很多文章中,都提到了移动构造,移动赋值这些,简单理解就是对资源的转移。
牵扯到C11的基本问题:右值是什么(在C11中右值的定义更加明确)。

函数重载:参数为引用接收时

下面三个函数可以重载,在之前的学习中,得知函数重载需要函数名相同,参数列表不同;
在C11中,参数的类型不同也可重载,比如下面就是左值引用和右值引用的区别。

void fun(int& a)
{
	cout << "fun(int& a)" << endl;
}

void fun(const int& a)
{
	cout << "fun(const int& a)" << endl;
}

void fun(int&& a)
{
	cout << "fun(int&& a)" << endl;
}

int main(void)
{
	int x = 10;
	const int y = 20;

	fun(x);
	fun(y);
	fun(30);

	return 0;
}

在运行后,可以看出编译器知道该把什么样的参数传给哪个函数:
在这里插入图片描述

但在与模板函数关联起来时,就会出现问题:

模板函数里调用重载的函数出现的问题

void fun(int& a)
{
	cout << "fun(int& a)" << endl;
}

void fun(const int& a)
{
	cout << "fun(const int& a)" << endl;
}

void fun(int&& a)
{
	cout << "fun(int&& a)" << endl;
}

template<typename T>
void fac(T&& a)
{
	fun(a);
}

int main(void)
{
	int x = 10;
	const int y = 20;

	fac(x);
	fac(y);
	fac(30);

	return 0;
}

运行结果:

这个函数将右值(30)当成了左值,调用了重载函数的第一个。
在这里插入图片描述

原因:
在右值具有名字后,在该示例中,30传递给模板函数的形参a,使其具有了别名,这时候就成了左值,所以调用的第一个已重载的函数。

解决方法:
完美转发(Perfect Forwarding)是指在函数模板中,完全依照模板的参数的类型(即保持参数的左值、右值特征),将参数传递给函数模板中调用的另外一个函数。C++11中提供了这样的一个函数std::forward,它是为转发而生的,不管参数是T&&这种未定的引用还是明确的左值引用或者右值引用,它会按照参数本来的类型转发。

示例:

void fun(int& a) //lvalue
{
	cout << "fun(int& a)" << endl;
}
void fun(const int& a)  // const lvalue
{
	cout << "fun(const int& a)" << endl;
}
void fun(int&& a) // rvalue
{
	cout << "fun(int&& a)" << endl;
}

template<typename T>
void fac(T&& a)
{
	fun(std::forward<T>(a));  // 完美转发
}

int main(void)
{
	int x = 10;
	const int y = 20;

	fac(x);
	fac(y);
	fac(30);

	return 0;
}

在这里插入图片描述

end

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_索伦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值