普通右值引用和 std::forward 返回的右值引用有什么区别?

What's the difference between an ordinary rvalue reference and one returned by std::forward?

我做不到:

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;

而且在右侧使用reference的时候,我其实是在使用referee。所以int &&r = q;可以认为是:

int &&r = temp;  //bind an lvalue to an rvalue reference, cause error, understandable

以上是我理解的编译错误发生的方式。


为什么加上std::forward可以解决这个问题?

int &&q = 7;
int &&r = std::forward<int>(q);

我知道 std::forward 总是 returns 右值引用,std::forward 返回的引用与 int&&q 有何不同?

how is the reference returned by std::forward different from int&&q ?

他们的value categories不一样。并注意类型和值类别是不同的东西。

q是一个命名变量,它被限定为lvalue,所以它不能绑定到右值引用。

(强调我的)

the name of a variable, a function, a template parameter object (since C++20), or a data member, regardless of type, such as std::cin or std::endl. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;

虽然从函数返回的右值引用被限定为 xvalue, which belongs to rvalue

a function call or an overloaded operator expression, whose return type is rvalue reference to object, such as std::move(x);

表达式qstd::forward<int>(q)的区别在于前者是左值,后者是右值(基本类别xvalue)。

我在 中解决了类似的问题:要点是 q 作为表达式是一个 左值 ,因为它有一个名称。 std::forward<int>(q)(或等效的 std::move(q))是没有名称的表达式,并且由于它们 return(未命名)右值引用,它们是 xvalues,它是 rvalue 的子类别并且可以因此绑定到右值引用。