C++中的左值和右值

6
好的,我一直在学习有关 lvalue 和 rvalue 的知识 - 请问精通 C/C++ 的人能告诉我我的想法是否正确吗?
考虑下面的代码:
int i = 3;
int j = i;

这里有两个左值 ij,当将 i 赋值给 j 时,i 变成了一个隐式的右值,因为 i 的一个副本被存储在 j 中。但是如果代码看起来像这样:
int i = 3;
int j = &i;

由于它们都是内存中的物理地址,所以j&i都是左值吗? 我的理解是右值是临时数据,而左值具有可引用的物理/引用内存地址。
如果有任何澄清,那就太棒了!

4
我推荐Strachey (1967)的第二部分。 - molbdnilo
谢谢@molbdnilo - 我现在会查看那个参考资料。 - Halfpint
@molbdnilo 链接已过期。它说:“在此服务器上未找到所请求的URL /courses/BPRD/E2009/fundamental-1967.pdf。” - Rohan Bari
1
@RohanBari 想象一下,仅六年后就会失效的网络链接。这里有一个链接,应该能持续一段时间:https://en.wikipedia.org/wiki/Fundamental_Concepts_in_Programming_Languages - molbdnilo
3个回答

8
变量i从未停止成为lvalue。如果您可以将地址运算符应用于某些内容(例如第二个示例中所做的),则它是lvalue。

另外,在第二个示例中,&i是指向i的指针,并且具有类型int*。在声明j和要使用它初始化的值之间存在类型不匹配。

最后,虽然i本身是一个lvalue,但表达式&i不是lvalue,因为您无法对其应用地址运算符(即您无法执行&&i)。


5
这里有两个左值ij
是的。
i被赋值给j时,它变成了一个隐式右值,因为i的副本存储在j中。
不完全正确,i仍然是一个左值,但它被转换为右值以读取其值。这称为左值到右值转换。 j仍然是一个左值。 j是一个左值,但&i是一个右值;具体来说是类型为int*的prvalue。

有趣 - 感谢您对“&i”变成“int*”的解释,这很有道理。 - Halfpint

4

作为表达式的一个属性,它是左值(lvalue)还是右值(rvalue)。通常,所有构成非常量限定符标识符的表达式都是可修改的左值(modifiable lvalues)

int i = 5;
i; // the expression "i" is an lvalue and is modifiable

const int j = 3;
j; // the expression "j" is still an lvalue, but not modifiable

一个左值表达式(除非带有const修饰符)可以通过任何赋值、++--运算符进行修改。也可以在这样的表达式上应用& "取地址"运算符。

一些运算符,如一元*、数组下标运算符[].->运算符也生成左值。这意味着你可以说,例如,*p=3,或a[i]=5,或b.c++&c->d

另一方面,不是左值的表达式是右值(它们是临时的,不能被修改)。如果你写类似于3=57++的内容,则编译器会抱怨37子表达式不是左值。


1
它们是临时的,不能被修改,但这并不一定是真的。例如std::string{} = "hi"是完全有效的。 - TartanLlama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接