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&
该死,这太难了。我现在明白了一点,再次感谢你,袁瑶。“瑞克试着总是单独考虑类型和价值类别,它会变得更加清楚。”