C++ 完美转发

本文探讨了C++中的左值引用、右值引用和完美转发的概念,重点解析了函数模板如何根据实参类型调用对应函数,以及完美转发在处理左值与右值转换中的作用。通过实例展示了如何避免voidfac函数的行为未定义,确保正确调用不同类型的函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

左值右值

void fun(int& a)
{	
	cout << "fun(int& a)" << endl;
}
void fun(const int& a)
{
	cout << "const int& a" << endl;
}
void fun(int&& a)
{
	cout << "fun(int&& a)" << endl;
}
template<class T>
void fac(T&& a)  //右值引用 称之为行为未定义
{
	fun(a);
}
int main()
{
	int a = 10;
	const int b = 20;
	const int& x = b;
	const int& y = 20;
	
	fun(a);
	fun(b);
	fun(10);

	return 0;
}

在这里插入图片描述
即使我们将 void fun(int&& a){} 删除,fun(10),会去调用所谓的万能引用 void fun(const int& a){};也就是说fun(10)会优先调用右值引用,如果没有右值引用,则会退而求其次调用常因用

template<class T>
void fac(T&& a)
{
	cout << std::is_lvalue_reference<T>::value << endl;
}
int main()
{
	int a = 10;
	const int b = 20;
	
	fac(a);
	fac(b);
	fac(10);

	return 0;
}

该模板对无论左值右值都可以进行调用,并且fun(10),在调动中既不属于右值也不属于左值
在这里插入图片描述
在这里插入图片描述

void fun(int& a)
{	
	cout << "fun(int& a)" << endl;
}
void fun(const int& a)
{
	cout << "const int& a" << endl;
}
void fun(int&& a)
{
	cout << "fun(int&& a)" << endl;
}
template<class T>
void fac(T&& a)
{
	fun(a);
}
int main()
{
	int a = 10;
	const int b = 20;
	const int& x = b;
	const int& y = 20;
	
	fac(a);
	fac(b);
	fac(10); //进入函数成为了具名变量

	return 0;
}

根据上面代码,按常理我们可以分析出,fac(a) 去调用 void fun(int& a),fac(b) 调用 void fun(const int& a),fac( c ) 调用 void fun(int&& a)

在这里我们的 void fac(T&& a) ,变量a属于20的别名,那么一旦右值拥有了名字,就会变成左值继而调用void fun(int& a);
在这里插入图片描述

完美转发

系统为了解决上面代码中的问题,给出了一个新的概念:完美转发

void fac(T&& a)
{
	//fun(a);
	fun(std::forward<T>(a));
}
int main()
{
	int a = 10;
	const int b = 20;
	const int& x = b;
	const int& y = 20;
	
	fac(a);
	fac(b);
	fac(10);

	return 0;
}

在这里插入图片描述
在整个过程中,可以保持a是20的左值的同时,在进行调用的时候依然可以将其看作一个右值

所谓完美转发(perfect formarding),是指在函数模板中,完全依照模板的参数的类型,将参数传递给函数模板中调用的另外一个函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值