左值与右值在C++标准中的表述

VC2010中给出了几个激动人心的特性,为了更好的了解右值引用带了的激动人心的性能提升,我们需要了解左值与右值的一些概念。

 

摘自C++标准2003版本,第三章

 

1 Every expression is either an lvalue or an rvalue.

表达式不是左值便是右值

 

2 An lvalue refers to an object or function. Some rvalue expressions—those of class or cv-qualified class type—also refer to objects.

左值是对象(指针,对象实例)或者函数(比如返回引用的函数,这里有一点很重要只有声明没有初始化的就不能成为左值,比如char* p;初始化为空*p不是左值,因为*p不是对象)一些右值也是对象(另外一些右值是宏定义的常量、整形字面量、字符串字面量、浮点数字面量等)

 

3 [Note: some built-in operators and function calls yield lvalues.

   [Example: if E is an expression of pointer type, then *E is an lvalue expression referring to the object or function to which E points. As another example, the function

int& f();

 yields an lvalue, so the call f() is an lvalue expression. ] ]

 

一些内建的操作符和函数调用会产生左值。E的指针类型,(E* p = new E;那么E调用dereference operator *后,)*E是左值表达式。再比如函数调用int& f()也产生左值,调用f()就是左值表达式。

 

4 [Note: some built-in operators expect lvalue operands. [Example: built-in assignment operators all expect their left hand operands to be lvalues. ]

Other built-in operators yield rvalues, and some expect them.

[Example: the unary and binary + operators expect rvalue arguments and yield rvalue results. ] The discussion of each built-in operator in clause 5 indicates whether it expects lvalue operands and whether it yields an lvalue. ]

 

一些内建的操作符需要左值操作数,比如内建的赋值操作符需要左操作数是左值。另外的一些内建的操作符函数则返回右值,或者需要参数为右值。

例如,一元和二元+操作符函数期望右值参数并且返回右值,5条款会解释如何判断函数返回值是否是左值或者参数是否需要左值。

 

5 The result of calling a function that does not return a reference is an rvalue. User defined operators are functions, and whether such operators expect or yield lvalues is determined by their parameter and return types.

 

调用返回值不为引用的函数得到的是对象是右值,用户自定义的操作符是普通函数,这些函数是否返回左值,参数是否需要左值是由函数的形参和返回值决定。

 

6 An expression which holds a temporary object resulting from a cast to a nonreference type is an rvalue (this includes the explicit creation of an object using functional notation (5.2.3)).

转换(包括explicit类型转换,强制转换等)自临时变量但是结果为非引用的表达式是右值。

7 Whenever an lvalue appears in a context where an rvalue is expected, the lvalue is converted to an rvalue; see 4.1, 4.2, and 4.3.

当左值出现在需要右值的地方,左值会转化为右值。

 

8 The discussion of reference initialization in 8.5.3 and of temporaries in 12.2 indicates the behavior of lvalues and rvalues in other significant contexts.

引用初始化(相关的问题)和临时变量阐述了左值和右值在其他一些重要场合的行为。

 

9 Class rvalues can have cv-qualified types; non-class rvalues always have cv-unqualified types. Rvalues shall always have complete types or the void type; in addition to these types, lvalues can also have incomplete types.

基于类的右值可以使用cv修饰类型,而非类(built-in的那些int, double等)的右值对象通常是不需cv修饰的类型(对于右值是什么类型判断,这句话似乎没有多大作用)。右值需要完整的类定义或者是void类型,另外,左值可以是非完整定义的类型。

 

10 An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [Example: a member function called for an object (9.3) can modify the object. ]

为了修改对象必需使用左值。当然也有一种特例,右值对象通过调用自己的成员函数来修改自身。

 

11 Functions cannot be modified, but pointers to functions can be modifiable.

函数不能被修改,但是指向函数的指针可以被修改。

 

12 A pointer to an incomplete type can be modifiable. At some point in the program when the pointed to type is complete, the object at which the pointer points can also be modified.

一个非完整定义的指针可以被修改。一个完整类型的指针指向的对象可以被修改,前提是该指针指向的内容合法

 

13 The referent of a const-qualified expression shall not be modified (through that expression), except that if it is of class type and has a mutable component, that component can be modified (7.1.5.1).

const修饰的表达式不能被修改(或者不能通过表达式来修改),比如const修饰的函数,除非是类并且包含了mutable修饰的实例,mutable修饰的实例才能被修改。

 

14 If an expression can be used to modify the object to which it refers, the expression is called modifiable. A program that attempts to modify an object through a nonmodifiable lvalue or rvalue expression is illformed

如果表达式可以修改对象,那么表达式就是可修改的,左值表达式包含可修改表达式。代码尝试修改不可修改的左值(比如const int a=0;)或者右值表达式将是非法的。

 

15 If a program attempts to access the stored value of an object through an lvalue of other than one of the fol-lowing types the behavior is undefined:
— the dynamic type of the object,
— a cv-qualified version of the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,

— an aggregate or union type that includes one of the aforementioned types among its members (includ-ing, recursively, a member of a subaggregate or contained union),
— a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
— a char or unsigned  char type.

 

 

上述可以,标准并没有给出一个定义什么是左值,什么是右值,只给出了一些判断左值和右值的方法,第一条是最关键的,表达式要么是左值要么是右值。函数调用(包括转换函数、包括operator函数),返回引用的是左值表达式,返回非引用的是右值表达式。

 

感觉有些地方还有不妥当之处,敬请斧正。

 

注:红色为注释内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值