Forward用来把是一个引用的参数传递出去。这可以是左值引用也可以是右值引用
这个引用如果不是形式上被声明成右值,那多半是用错了,这里是一个使用例子
template<typename T>
void CallPrint(T&& x)
{
Print(std::forward<T>(x));
}
forward中接受的参数是通过函数传递进来的右值引用
使用forward的时候,不能忽略它的模板参数。最好的写法是
被forward的参数的类型如果声明为x&&,那么就要写std::forward<x>。
其中:当X是一个非引用类型的时候,forward会把类型为x&&的参数处理成右值引用。如果X是一个左值引用类型的时候,forward会把类型为x&&的参数处理成左值引用
我们来看这么一个例子:
#include <iostream>
using namespace std;
void Print(int& x)
{
cout << "x is int&" << endl;
}
void Print(int&& x)
{
cout << "x is int&&" << endl;
}
template<typename T>
void CallPrint(T&& x)
{
Print(std::forward<T>(x));
}
int main()
{
int x = 0;
CallPrint(x);
CallPrint(0);
system("PAUSE");
return 0;
}
CallPrint(x)的类型计算过程是,首先x的类型是int&,但是callPrint的参数却是T&&,由于类型折叠的关系,想让T&&变成int&,那么T只能是int&,然后int& &&只能是int& 了所以调用forward的时候其模板参数是T,也就是int&
Print(std::forward<T>(x));也就是一个T了
CallPrint(0)的类型计算过程是,首先0的类型是constexpr int(也就是说他需要的时候可以被看成int,const int const int&等) 但是callPrint的参数是T&&。那么T就只能是int所以调用forward的时候,通过模板参数T进行传递
参数推导出来是左值引用就是左值引用,推导出来是右值引用就是右值引用
我们
MOVE:MOVE用来说明一个左值引用的对象已经不需要再被使用了
class ClassRoom
{
private:
vector<string> students;
public:
ClassRoom()
{
}
ClassRoom(const ClassRoom& classRoom)
:students{classRoom.students}
{
}
ClassRoom(ClassRoom&& classRoom)
:students{std::move(classRoom.students)}
{
}
在这里有两个构造函数:第一个是直接左值引用构造函数
第二个函数参数使用了右值引用,但为什么还要使用move进行左值引用传值呢
虽然classRoom声明为一个右值引用但是classroom.students是一个左值引用,所以需要用move。而且forward的一大作用就是把声明为右值引用的参数传递给别人并且以后再也不使用它classRoom.student不是参数,classroom才是
即必须以函数传入的参数为准,classRoom.student不是函数传入的参数,所以是左值引用