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