C++ 什么';普通右值引用和std::forward返回的右值引用之间的区别是什么?
我不能这样做:C++ 什么';普通右值引用和std::forward返回的右值引用之间的区别是什么?,c++,c++11,rvalue-reference,value-categories,C++,C++11,Rvalue Reference,Value Categories,我不能这样做: int &&q = 7; int &&r = q; //Error Message: //cannot convert from 'int' to 'int &&' //You cannot bind an lvalue to an rvalue reference 如果我理解正确的话,在初始化右值引用时,也会初始化一个临时变量。因此int&&q=7可被视为: int temp = 7; int &&q = te
int &&q = 7;
int &&r = q;
//Error Message:
//cannot convert from 'int' to 'int &&'
//You cannot bind an lvalue to an rvalue reference
如果我理解正确的话,在初始化右值引用时,也会初始化一个临时变量。因此int&&q=7代码>可被视为:
int temp = 7;
int &&q = temp;
int &&r = temp; //bind an lvalue to an rvalue reference, cause error, understandable
当在右边使用参考时,我实际上是在使用裁判。所以int&&r=q代码>可被视为:
int temp = 7;
int &&q = temp;
int &&r = temp; //bind an lvalue to an rvalue reference, cause error, understandable
以上是我对编译器错误发生的理解
为什么添加std::forward
可以解决这个问题
int &&q = 7;
int &&r = std::forward<int>(q);
int&&q=7;
int&&r=std::forward(q);
我知道std::forward
总是返回一个右值引用,那么std::forward
返回的引用与int&&q
有何不同
std::forward
返回的引用与int&&q
返回的引用有何不同
他们是不同的。请注意,类型和值类别是不同的
q
是一个命名变量,它被限定为,因此不能绑定到右值引用
(强调矿山)
变量、函数、模板参数对象(自C++20以来)或数据成员的名称,无论其类型如何,如std::cin
或std::endl
即使变量的类型是右值引用,由其名称组成的表达式也是左值表达式强>
而从函数返回的右值引用限定为,它属于
函数调用或重载运算符表达式,其返回类型为对对象的右值引用,例如std::move(x)
表达式q
和std::forward(q)
之间的区别在于前者是左值,而后者是右值(基本类别xvalue)
我在中提到了类似的问题:重点是q
作为一个表达式是一个左值,因为它有一个名称std::forward(q)
(或等效的std::move(q)
)是没有名称的表达式,因为它们返回(未命名的)右值引用,所以它们是xvalues,它是右值的子类别,因此可以绑定到右值引用。等效的与相同的不同。硬编码的值不被视为正则变量。我认为我无法比Scott更好地解释它,所以请检查以下内容:正如其他人所暗示的,int&&r=std::move(q)在这种情况下,代码>将是执行强制转换的更惯用的方式std::forward
用于“完美转发”,传递具有模板类型的参数,例如template void f(T&&x)
或template void f(T&&x)
另一个可能的惊喜:decltype(q)
相当于int&
而decltype((q))
相当于int&
该死,这太难了。我现在明白了一点,再次感谢你,袁瑶。“瑞克试着总是单独考虑类型和价值类别,它会变得更加清楚。”