在C/C ++中,“lvalue”和“rvalue”的命名背后的原因是什么?
标准提到了这个:
一个左值(历史上称为左值,因为左值可以出现在赋值表达式的左侧)[...]
一个右值(历史上称为右值,因为右值可以出现在赋值表达式的右侧)[...]
也就是说,一个左值是你可以赋值的东西,而一个右值是你可以从中赋值的东西。
然而,这与事实逐渐越来越远。一个无法分配的左值的简单例子是一个const
变量。
const int x = 5;
x = 6; // Error
当涉及操作符重载时,您甚至可以在赋值的左侧出现右值。
我认为将lvalue视为引用存储在内存中的对象,将rvalue视为仅仅是一个值(可能已经从内存中读取)。这些概念很好地反映了这个想法。以下是一些示例:
&
)需要一个lvalue,因为你只能获取内存中的某个东西的地址。它不需要获取对象的值来计算其地址。std::move
将lvalue表达式转换为rvalue表达式可以被看作是欺骗编译器,使其认为存储在内存中的对象实际上只是临时值。然而,在每种情况下都不能保持这样的说法。这只是个合理的类比。
早期,“lvalue”指的是可以放在赋值语句左侧的内容,而“rvalue”则指可以放在赋值语句右侧的内容。
如果你考虑到赋值运算符的哪一侧可以出现它们,那么这是相当直观的:
left-value = right-value;
简单来说,lvalue
表示可以对其进行赋值,而 rvalue
只能出现在操作符的右侧。
lvalue
和rvalue
反映了赋值运算符的用法。 rvalue
只能出现在=
的右边,而lvalue
可以出现在任一侧。在C++中,情况类似,但更加复杂。lvalues
,即常量变量。'l'在lvalue中的起源是来自于“left” value(即赋值运算符左侧); 然而,现在它代表位置值,并且指任何占据某个可识别内存位置的对象(即具有地址)。rvalue现在是指任何不是lvalue的东西。
这是对一个(稍微复杂一些的)概念简化后的结果。
lvalue
是左值,即“可以出现在赋值语句的左侧”的值。这是一个简化,不是所有的左值都可以直接按原样分配(例如,数组不能,只有非 const
数组的元素可以,因此需要使用下标)。
rvalue
是右值,即只能出现在赋值表达式的右侧的值。