这个问题rvalue
很好,因为它回答了, lvalue
, xvalue
,glvalue
和之间的区别prvalue
。最佳答案对每个都有一个不错的解释,当我阅读它们时,我理解它们的区别。但是,我很难将它们牢牢记在脑海中,每次有人使用这些术语来提醒自己哪个是哪个时,我都必须在谷歌上搜索它们。
人们是否有任何常见的助记符或其他方式记住哪个是哪个?我真的很希望能够将它们全部记在脑海中,而不会像现在这样混淆它们。
我做了两个关联:
std::move
表达式如果两者都不是,那么它可能是一个prvalue。
现在,为了记住 glvalues 和 rvalues,我简单地想象这个图:
lvalues 和 xvalues 都是 glvalues,而 xvalues 和 prvalues 都是 rvalues。这就是您在实践中需要知道的全部内容。
也许记住 lvaluse、xvalues 和 prvalues 的助记符在底部是单词Lower eXPRessions
(它包含 L、X 和 PR)。也许不吧。
您通常只需要知道某个东西是左值还是右值。这两类表达方式彼此不同。
通常情况下,左值表达式指的是会出现一段时间的东西。例如,变量名称是左值,因为变量会一直存在。另一方面,右值表达式通常指的是暂时存在的东西。您只能获取左值的地址,因为到底为什么您需要即将消失的东西的地址?
现在,在进行这种区分时,您必须考虑编译器当时所知道的内容。以函数为例void foo(const A& a)
。在这个函数内部,编译器不知道传递的对象是否是临时对象,所以它只是假设它会一直存在。也就是说,a
是一个左值。即使您可以愉快地将临时对象传递给此函数(使用右值表达式调用它),该表达式a
仍然是左值。
考虑到这一点,您可以通过是否命名来进一步记住某物是左值还是右值。在上面的例子中,由于对象被命名为a
,它是一个左值。
现在,对于其余类别,您应该记住下图:
请注意,左值和右值确实是不同的。然而,右值被分成另外两个类别,xvalues 和 prvalues。此外,xvalues 也被认为是 glvalues 以及所有左值表达式。
现在知道这些何时出现归结为记住一些案例。
xvalues不是很常见。它们只出现在涉及转换为右值引用的情况下。以下是所有案例:
object.x
如果object
是一个 xvalueobject.*member
如果pobject
是一个 xvalue根据定义,纯右值是不是 xvalue 的所有其他类型的右值。例如,从函数中按值返回对象会创建一个临时返回对象。表示该对象的表达式是纯右值。
类别glvalue用于指代不是纯右值的所有内容。
左值可以被认为是“命名”变量或内存位置......右值可以被认为是“未命名”内存位置(即,从函数返回的临时变量)或纯“值”(即,就像一个数字)。