我发布了这个答案:https://stackoverflow.com/a/28459180/2642059其中包含以下代码:
void foo(string&& bar){
string* temp = &bar;
cout << *temp << " @:" << temp << endl;
}
bar
是右值还是左值?
我问是因为我显然不能获取右值的地址,但我可以像这里所做的那样获取右值引用的地址。
如果您可以对右值引用执行您可以对左值引用执行的任何操作,那么使用“&&”而不是仅仅使用“&”来区分两者有什么意义?
最佳答案
Is
bar
an rvalue or an lvalue?
问题自己回答。任何有名字的都是左值(1)。所以 bar
是一个左值。它的类型是“string
的右值引用”,但它是该类型的左值。
如果您想将其视为右值,则需要对其应用 std::move()
。
If you can perform any operation on an rvalue reference that you can on an lvalue reference what is the point in differentiating between the two with the "&&" instead of just an "&"?
这取决于您对“执行操作”的定义。左值引用和(命名的)右值引用在如何在表达式中使用它们方面几乎相同,但它们在可以绑定(bind)到它们的内容上很多。左值可以绑定(bind)到左值引用,右值可以绑定(bind)到右值引用(任何东西都可以绑定(bind)到 const
的左值引用)。也就是说,您不能将右值绑定(bind)到左值引用,反之亦然。
我们来谈谈右值引用类型的函数参数(比如你的bar
)。重要的一点不是 bar
是什么,而是您对 bar
引用的值了解多少。由于 bar
是一个右值引用,您可以肯定地知道绑定(bind)到它的任何东西 都是一个右值。 这意味着它一定会在完整表达式结束时被销毁,并且您可以安全地将其视为右值(通过窃取其资源等)。
如果您不是直接对 bar
执行此操作的人,而只是想传递 bar
,您有两个选择:要么完成 bar
,然后你应该告诉下一个接收它的人它绑定(bind)到一个右值——执行 std::move(bar)
。或者你需要用 bar
做更多的事情,所以你不希望中间的任何人从你下面窃取它的资源,所以把它当作一个左值——bar
.
总结一下:区别不在于您拥有引用后可以对其执行的操作。区别在于可以绑定(bind)到引用的内容.
(1) 一个很好的经验法则,但有一些小异常(exception):枚举数有名称,但是是右值。类、命名空间和类模板有名称,但没有值。
关于c++ - 右值引用被视为左值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52142104/