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

Ric*_*ick 17 c++ rvalue-reference c++11 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
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,在初始化右值引用时,也会初始化一个临时变量.所以int &&q = 7;可以认为是:

int temp = 7;
int &&q = temp;
Run Code Online (Sandbox Code Playgroud)

当在右侧使用参考时,我实际上是在使用裁判.所以int &&r = q;可以认为是:

int &&r = temp;  //bind an lvalue to an rvalue reference, cause error, understandable
Run Code Online (Sandbox Code Playgroud)

所以上面是我理解编译器错误发生的方式.


为什么添加std::forward可以解决?

int &&q = 7;
int &&r = std::forward<int>(q);
Run Code Online (Sandbox Code Playgroud)

我知道std::forward总是返回一个右值引用,引用的引用是如何std::forward不同的int&&q

son*_*yao 13

如何返回std::forward不同的引用int&&q

他们的价值观类别不同.请注意,类型和值类别是不同的东西.

q是一个命名变量,它被限定为左值,因此它不能绑定到右值引用.

(强调我的)

一个变量,函数,模板参数的对象的名称(因为C++ 20),或一个数据成员,而不管类型,如std::cinstd::endl.即使变量的类型是右值引用,由其名称组成的表达式也是左值表达式;

虽然从函数返回的rvalue引用被限定为xvalue,它属于rvalue.

函数调用或重载的运算符表达式,其返回类型是对象的右值引用,例如std::move(x);

  • @Rick尝试始终分别考虑类型和值类别,它会变得更加清晰. (4认同)

Rei*_*ica 10

表达式之间的差qstd::forward<int>(q)是,前者是一个左值,而后者则是(基本类别x值)右值.

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