#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();
//}
完美转发forward
最新推荐文章于 2024-11-09 19:34:49 发布