指针是左值还是右值?

8

在另一篇文章中,我遇到了以下内容:

(5.2.9/8) 类型为“指向类型为cv1 T的D类成员”的右值可以转换为类型为“指向类型为cv2 T的B类成员”的右值,其中B是D类的基类(第10条款),

请注意这是语言标准中的内容。因此我的问题是,

int i = 0;
int *p = &i;
*p = 1;

指针在所有情况下都是左值吗?什么时候会被视为右值?


2
在你的程序的第二行中,表达式&i是一个类型为int*的表达式,因此是指针被视为rvalue的一个例子。你正在将表达式&i的结果作为赋值运算符的rvalue,并使用int *p作为该运算符的lvalue。 - matthias
1个回答

23

指针并不是可以作为 rvalue 或 lvalue 的类型,指针是一个类型。唯一可以作为 rvalue 或 lvalue 的是表达式。

考虑下面类似的问题:“整数是一个 lvalue 还是 rvalue”,实际上都不是。例如,数字“3”是一个整数且是 rvalue。语句 3=i; 是非法的。但如果 i 是一个整数,语句 i=3; 是合法的。所以 i 是一个整数且是 lvalue,而 3 是一个整数且是 rvalue。


请您能否使用我的示例来展示发生了什么?以及为什么语言标准会这样规定?谢谢。 - user1086635
2
我不确定你具体在问什么。指针是lvalue还是rvalue的规则与任何其他表达式的规则相同。就像“3”是rvalue一样,“new foo(3)”也是rvalue。如果'j'是整数类型的变量,则“j”是lvalue,因此如果'j'是指针类型的变量,则“j”也是lvalue。就像整数类型的const引用是rvalue一样,指向整数的指针类型的const引用也是rvalue。类型只是无关紧要的。 - David Schwartz
据我理解,您写道:指针不能是左值或右值。那么在我的例子中:'p'不是左值吗?因为我可以取它的地址 &p。 - user1086635
4
是的,表达式 p 是一个左值,并且还是指针类型。你的问题就像是“思想有四个字母吗?”当我说“思想不是那种可以有四个字母的东西”时,你回答说“但 思想 确实有四个字母!” 一个表达式可以是左值或右值,但指针不行。指针类型的表达式可以是左值或右值,就像一个单词可以有四个字母,无论它是不是“思想”这个词。 - David Schwartz
我认为正如@DavidSchwartz所指出的那样,人们应该意识到lvalue和rvalue是表达式的属性。在表达式x = 5中,x是lvalue,5是rvalue;考虑另一个表达式x = y,在这里x是l-value,y是rvalue。(如果我在这里犯了错误,请有人纠正我-> int x;不是一个表达式,它更像是一个语句。lvalue和rvalue的属性只有作为表达式的属性时才会生效。) - pokche

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