完美转发forward

#include <iostream>
#include <vector>
#include <string>
using namespace std;

void test() {
	string A("abc");
	string&& Rval = std::move(A);
	string B(Rval);    // this is a copy , not move.
	cout << A << endl;   // output "abc"
	string C(std::forward<string>(Rval));  // move.
	cout << A << endl;       /* output "" */
}

//forward的由来:保持住参数的属性
//定义:完美转发是指函数模板在向其他函数传递自身形参时,
//相应实参是左值,则被转发为左值;同理如果相应实参为右值,则被转换为右值。

template<typename T>
void PrintT(T& t)
{
	cout << "lvalue" << endl;
}

template<typename T>
void PrintT(T&& t)
{
	cout << "rvalue" << endl;
}

//引用折叠与右值引用特殊类型推导决定了forward<T>中T的类型。

// 传入函数的参数四种类型:左值,右值,左引用,右引用。
//引用折叠规则:X& &、X& &&、X&& &都折叠成X& 。X&& &&折叠为X&&。
//右值引用特殊类型推导原则:
//原则一:如果函数传进的是个A类型的左值或左值引用,编译器推断模板参数T类型为 A的左值引用,即T被决议为A&。 
//原则二:如果函数传进的是个A类型的右值或右值引用,编译器推断模板参数T类型为 A类型,即T被决议为A。

//forward<>转换规则为:
//模板参数类型为T、T&&时,即forward<T>、forward<T&&> 返回右值引用
//模板参数类型为T&时,即forward<T&> 返回左值引用

template<typename T>
void TestForward(T&& v)
{
	//PrintT(v); //形参接受实参,形参全部变成左值,所以以下输出第一条全是lvalue
	PrintT(std::forward<T>(v));
	//PrintT(std::move(v));  //move全都变为右值,以下输出第三条全是右值
}

void testforward() {

	//根据右值引用特殊类型推到原则二:
	//编译器推断模板参数类型为A
	TestForward(1);                      //实参为右值
	TestForward<int>(1);     
	cout << endl;
	cout << "************************" << endl;

	int a = 0;
	//根据右值引用特殊类型推到原则二:
    //编译器推断模板参数类型为A
	TestForward(std::move(a));  //实参为右值引用
	TestForward(static_cast<int&&>(a));
	cout << "************************" << endl;

	int x = 1;
	//根据右值引用特殊类型推到原则一
	//编译器推断模板参数T类型为实参的左值引用
	TestForward(x);             //实参为左值
	TestForward<int&>(x);        

	cout << "************************" << endl;

	//根据右值引用特殊类型推到原则一
	//编译器推断模板参数T类型为实参的左值引用
	int& b = x;
	TestForward(b);             //实参为左值引用
	TestForward<int&>(b);

	cout << "************************" << endl;

	//forward<T>、forward<T&&>返回右值引用
	std::forward<int>(x);
	std::forward<int&>(x);
	std::forward<int&&>(x);

	TestForward(std::forward<int>(x));
	TestForward<int>(std::forward<int>(x)); //与上一条等价
	cout << endl;
	cout << "************************" << endl;

	int y = 2;

	//forward使用的时候需要指定类型
	//指定类型不同,返回结果不同
	std::forward<int>(y);       //forward<T>返回右值引用
	std::forward<int&>(y);   	//forward<T&>返回左值引用
	std::forward<int&&>(y);   	//forward<T&>返回右值引用
	                     
	TestForward(std::forward<int>(y));    //右
	TestForward(std::forward<int&>(y));   //左
	TestForward(std::forward<int&&>(y));  //右

	TestForward(std::forward<int&&>(5));  //右
	TestForward(std::forward<int>(5));  //右
	//TestForward(std::forward<int&>(5));  //此语句错误

	cout << "************************" << endl;

	//传递指针和T情况一样
	int* p = &y;
	std::forward<int*>(p);
	TestForward(std::forward<int*>(p));
	TestForward(std::forward<int*&>(p));
	TestForward(std::forward<int*&&>(p));
	cout << endl;
}


//int main()
//{
//	testforward();
//}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值