当前位置:  开发笔记 > 程序员 > 正文

经常使用很少定义的术语:左值

如何解决《经常使用很少定义的术语:左值》经验,为你挑选了4个好方法。

什么是左值?



1> Chris Lutz..:

左值是可以被分配给一个值:

lvalue = rvalue;

这是短期的"左值"或"左侧值",它基本上只是数值上的左边的的=迹象,即价值分配的东西.

作为不是左值的例子(即仅rvalue):

printf("Hello, world!\n") = 100; // WTF?

该代码不起作用,因为printf()(返回一个函数int)不能是左值,只能是右值.


+1好看!"// WTF"让我开怀大笑!但是,如果printf返回引用,它将有资格作为左值.

2> 小智..:

出现在赋值左侧的东西,即可以分配给它的东西.

请注意,在C++中,函数调用可能是左值,如果:

int & func() {
   static int a = 0;
   return a;
}

然后:

func() = 42;     // is legal (and not uncommon)


不是那么奇怪 - 它是operator []正常工作的方式

3> Johannes Sch..:

它传统上是"="运算符的左侧.但是,随着时间的推移,"左值"/"右值"的含义发生了变化.C++添加了一个"不可修改的左值"的术语,它是任何无法赋值的左值:数组和用"const"限定的变量是两个例子.在C中,您不能分配任何右值(见下文).同样,在C++中,您不能分配给某些用户定义的类类型的rvalues.

您可以说"左值"是一个表达式,用于命名随时间持续存在并占据存储位置的对象.是否可以分配该表达式对于该分类并不重要.特别是,引用也是左值,因为它的名称会随着时间的推移而持续存在.以下所有都是左值,因为它们都引用了命名对象.另请注意,a const对左值没有任何影响.

int a; lvalue: a;
       lvalue: ++a;
int a[2]; lvalue: a;
int &ra = a; lvalue: ra;
int *pa = &a; lvalue: *pa;

术语"rvalue"用于文字和枚举器值以及不享受长寿的乐趣的临时演员,并且在完整表达结束时立即被销毁.对于右值,不是持久性方面很重要,而是价值方面.C++中的函数是左值,因为它们是持久的并且它们具有地址,即使它们不是对象.我在上面的左值概述中将它们排除在外,因为当首先考虑对象时,更容易掌握左值.以下所有是rvalues:

enum { FOO, BAR }; rvalue: BAR;
int a[2]; rvalue: (a+1);
rvalue: 42;
int a; rvalue: a++; // refering to a temporary
struct mystruct { }; mystruct f() { return mystruct(); } rvalue: f();

顺便提一下,通常你有一个左值,但是运算符需要一个右值.例如,二进制内置"+"运算符添加两个值.首先和全部的左值表达式指定首先必须读出值的位置.因此,当您添加两个变量时,会发生"左值到右值"转换.标准表示左值表达式中包含的值是其右值结果:

int a = 0, b = 1;
int c = a + b; // read values out of the lvalues of a and b. 

其他运营商不采用右值,而是左值.他们没有阅读价值.一个例子是address-of运算符,&.您不能获取右值表达式的地址.有些rvalues甚至不是对象:它们不占用任何存储空间.例如,文字(10,3.3,...)和枚举值.

那些可怕的东西有用吗?

好吧,它具有区分左值和右值的几个优点

允许编译器省略为rvalues存储存储并使用寄存器/只读存储器作为标量值

将表达式标记为难以捉摸:rvalues不会长寿

允许编译器在内部和c ++ 1x中有效的复制语义也暴露给程序员(参见移动语义和右值引用):我们可以从可能被销毁的rval中窃取资源.

允许在该属性上构建规则

不允许从左值所指的尚未初始化的对象生成rvalues.但是左值可以指未初始化的对象

rvalues永远不会是多态的.它们的静态类型也必须是它们的动态类型:简化typeid运算符的规则.

......还有更多,我觉得......



4> Nemanja Trif..:

我知道的最好的解释之一可以在这篇关于RValue参考的文章中找到.

确定表达式是否为左值的另一种方法是询问"我可以取其地址吗?".如果可以的话,这是一个左值.如果你做不到,这是一个左值.例如,&obj,&*ptr,&ptr [index]和&++ x都是有效的(即使其中一些表达式是愚蠢的),而&1729,&(x + y),&std :: string("喵" ")和&x ++都是无效的.为什么这样做?地址运算符要求其"操作数应为左值"(C++ 03 5.3.1/2).为什么需要呢?获取持久对象的地址是可以的,但是获取临时对象的地址会非常危险,因为临时对象会迅速消失.

推荐阅读
家具销售_903
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有