先看一种情况,它的输出结果是什么?
#include <iostream>
using namespace std;
void F(const int &a)
{
cout << "int: " << a << endl;
}
void F(int &&a)
{
cout << "int &&: " << a << endl;
}
template <typename T>
void G(T &&t)
{
return F(t); // 1 direct call
// return F(std::forward<T>(t)); // 2 forward call
}
int main()
{
int i = 1;
G(i);
G(2);
return 0;
}
Output:
int: 1
int: 2
这就不符合我们的预期呀,我们希望G(i)调用左值函数,G(2)调用右值函数,而实际上两者都调用的左值函数。因此,需要std::forward
如果我们采用第2种,输出是什么呢?
return F(std::forward<T>(t)); // 2 forward call
Output:
int: 1
int &&: 2
OK, nice
为什么会这样呢,根本原因在于右值引用指向右值,但本身是左值,也就是说T&& t
中,t指向右值,但t本身是左值。
所以,如果不采用发转,不管传进来的是右值,经过右值引用也会变成左值,从而去调用左值函数
用forward
所以,universal reference 转发时并不完美,只完美了一半,当转发目标的的参数是右值引用时,会出现问题。
std::forward 解决当转发目标的的参数是右值引用时的问题。可以保持原始参数的类型,将实参从原来的类型为右值引用的左值,变成了本身就是右值引用
std::forward
做了什么,为什么可以保持类型不变?
标签:std,右值,int,左值,C++,&&,forward From: https://www.cnblogs.com/lfri/p/16588306.htmlC++11为什么要引入 右值引用 这个概念? 它与左值引用有什么本质区别?实际上二者在编译后的汇编层面,就是变量的地址,没有任何区别。那么为什么“画蛇添足”增加个 右值引用 概念?因为要在编译时告诉编译器,这里传入的 “变量的地址”,是个普通变量还是濒死的除了此处不再使用的变量。如果是后者,可以用move语义,直接把它的内容、资源给搬走,不用“深拷贝”了。所以题主的问题,对于函数模板 void G(A &&a),它的内部怎么知道形参对应的实参,是个普通变量,还是濒死的临时变量? 答案是,显然、当然没法知道,只能原封不动的完美的转发给函数模板 void G(A &&a)调用的下一层函数。这就是std::forward的用途。如果你用Visual C++,你可以直接搜一下它所带的STL源代码中std::forward的实现。实际上std::forward啥都不做,就是取变量的地址而已。