`
yaogangshi
  • 浏览: 73279 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

左值与右值在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
1
分享到:
评论

相关推荐

    左值与右值的引用

    这是关于C++左值与右值引用的课程视频,课程易于理解,可以很快掌握

    C++中的左值和右值

    在C/C++中,左值(lvalue)和右值(rvalue)是用于规定表达式(expression)的性质。C++中表达式要不然是左值,要不然是右值。  这两个概念在C语言中比较容易理解:左值能放在赋值语句的左边,右值不能。但是当来到C++时...

    C语言指针以及区分左值和右值的技巧(整理)

    看了一下自己的资源,下载了很多,实在不好意思,整理一份发一下。 Android开发高效率的还是依靠NDK,所以C语言学习一下也是有必要的。Android内核还是Linux所以本分分类放在了Linux这里。其实我是想放到OS Android...

    左值和右值

    左值和右值

    左值,右值,引用,以及源代码

    左值,右值,引用,以及源代码

    关于i++和++i以及左值,右值

    本文主要讲了关于i++和++i以及左值,右值的问题,希望对你的学习有所帮助。

    C语言程序设计(第2版)-2期 拓展知识3-1 左值和右值.pdf

    C语言程序设计(第2版)-2期 拓展知识3-1 左值和右值.pdf 学习资料 复习资料 教学资源

    C++11中的左值引用和右值引用

    1.首先区分左值和右值  左值是表达式结束后依然存在的持久对象  右值是表达式结束时不再存在的临时对象  便捷方法:对表达式取地址,如果能,则为左值,否则为右值  举例:  int a = 10  int b = 20  ...

    cpp代码-左值 和 右值 ---- 左值引用(就是别名) 和 右值引用

    cpp代码-左值 和 右值 ---- 左值引用(就是别名) 和 右值引用

    非常量引用的初始值必须为左值的问题

    C++ 11中引入的一个非常重要的概念就是右值引用。理解右值引用是学习“移动语义”(move semantics)的基础。而要理解右值引用,就必须先区分左值与右值。 对左值和右值的一个最常见的误解是:等号左边的就是左值,...

    浅谈C++左值引用和右值引用

    左值必须要在内存中有实体; 右值当在赋值号右边取出值赋给其他变量的值;右值可以在内存也可以在CPU寄存器。  一个对象被用作右值时,使用的是它的内容(值),被当作左值时,使用的是它的地址。 2、引用 引用是C++...

    c++的左值右值 i++与++i的区别.docx

    c++的左值右值 i++与++i的区别.docx

    31_c++中的左值引用与右值引用1

    左值:可以取地址的,有名字的,临时的右值:不能取地址的,没有名字的,临时的举个栗: int a = b + c ,a 就是左值,其变量名为 a ,通过 &a 可

    C++中关于左值和右值的讨论

    左值性(lvalueness)在C/C++中是表达式的一个重要属性。只有通过一个左值表达式才能来引用及更改一个对象(object)的值。(某些情况下,右值表达式也能引用(refer)到某一个对象,并且可能间接修改该对象的值,后...

    浅析C++11中的右值引用、转移语义和完美转发

     C++对于左值和右值没有标准定义,但是有一个被广泛认同的说法:可以取地址的,有名字的,非临时的就是左值;不能取地址的,没有名字的,临时的就是右值.  可见立即数,函数返回的值等都是右值;而非匿名对象(包括变量),...

    C++11中的右值引用

    在C++98中有左值和右值的概念,不过这两个概念对于很多程序员并不关心,因为不知道这两个概念照样可以写出好程序。在C++11中对右值的概念进行了增强,我个人理解这部分内容是C++11引入的特性中难以理解的了。该特性...

    c++重载增量运算符

    重载增量运算符在运用中的总结,主要左值与右值的区别

Global site tag (gtag.js) - Google Analytics