C ++标准版(4/5)未对左值进行左值到右值的转换 一元&的操作数操作
例如:
int x;
int *p = &x;
在上述情况下,p
是&x
两个左值吗?或者什么是恰当的例子?
修改
这个怎么样?
int &r = x;
我确定此声明中没有转换,但我很困惑& amp;运营商涉及到这个?
答案 0 :(得分:4)
引用说明转换不适用于一元&
的操作数(在本例中为x
)。所以&
的操作数是左值。
这与一元+
运算符不同。如果你写+x
,那么左值转换 应用于子表达式x
(在这种情况下具有未定义的行为,因为x
没有没有初始化。
非正式地,“左值到右值的转换”意味着“读取价值”。
引用没有说明&
的结果,实际上它是一个右值。在int *p = &x;
:
x
是一个左值,指的是该名称的变量&x
是一个右值,它是初始化程序的一部分(具体来说,是赋值表达式),p
既不是右值也不是左值,因为它不是(子)表达式。它是正在定义的变量的名称。在C ++声明符语法中,它是 declarator-id (C ++ 03标准中的8/4)。 int &r = x;
根本不使用&
地址运算符。声明符中的&
字符只是语法意味着r
是对int的引用,它不是r
的地址。在C ++声明符语法中,它实际上称为 ptr-operator 。
答案 1 :(得分:2)
将左值作为存储位置,将左值作为存储值。因此*p
是左值,&x
是左值。然而,&需要左值作为操作数(x),但结果是右值,但不更改x
本身。
答案 2 :(得分:1)
标准引用基本上表示&
适用的操作数,不会成为 rvalue 。它仍然是左值。
实际上,&
的操作数不能是 rvalue 。它必须是 lvalue ,否则将能够获得标准不允许的临时对象的地址:
struct A{};
int *addressOfTemporary_int_object = &(int(10)); //error
A *addressOfTemporary_A_object = &A(); //error
正是因为&
的操作数必须是 lvalue ,所以上述表达式是非法的,因为子表达式int(10)
和A()
是 rvalue 表达式,用于创建临时对象。
另请注意,即使表达式x
中的子表达式&x
是左值,在&
上应用x
的结果仍然是一个 rvalue 。也就是说,表达式&x
是 rvalue ,并且不能出现在赋值运算符的右侧:
&r = whatever; //illegal
我希望这可以帮助您理解报价。
这个怎么样?
int &r = x;
这没关系。此处&
使r
成为对象x
的引用。这里&
不是运算符,并且与引用r
无关,而是与类型相关联。将其写成以下内容并不那么令人困惑:
int& r = x;
//Or if you use typedef as
typedef int& intref;
intref r = x;
答案 3 :(得分:0)
“在操作数上”应该引用右侧的x
。也就是说,语句x
中的子表达式int *p = &x;
不是是一个右值,而是一个左值。将其与int a = b;
进行对比,其中子表达式b
是一个右值(转换后)。
答案 4 :(得分:0)
C ++ Standard(4/5)左值和右值的转换不是在一元&的操作数上完成的。操作
这句话只是为了让你迷惑。它没有其他目的。 ;)
最重要的引用是(引用N3242,所以新术语有“prvalue”而不是rvalue):
每当glvalue表达式作为操作符的操作数出现时,该操作符需要该操作数的prvalue,lvalue-to-rvalue(4.1),array-to-pointer(4.2)或function-to-pointer(4.3)应用标准转换以将表达式转换为prvalue。
因此,语言可以用期望prvalue和没有的结构的构造来描述。特别是,运算符&
不会“期望prvalue”(恰恰相反),因此左值到右值的隐式转换不是必需的,也不会应用。
标准描述不一致:它从未明确表示在x += y
中,左值到右值的隐式转换不适用于x
,大概是因为它非常明显。为什么作者觉得有必要明确地说明&x
,这在我看来是非常明显的。
我认为这些提及隐含的转化不应该被删除。标准描述了发生了什么,而不是(无限多)没有发生的事情(除非它不会发生,这是非常令人惊讶的。)
隐式转换仅适用于将表达式的“性质”调整为对上下文的期望(上下文可以是表达式,语句,声明,ctor-init-list ...)。
这个怎么样?
int &r = x;
我确信此声明中没有转换,
因为此处不需要隐式转换 。仅在需要时应用隐式转换。参考绑定不期望rvalue。
但是我很困惑&运营商涉及到这个?
不是。