文档章节

Effective C++: expression value category

SHIHUAMarryMe
 SHIHUAMarryMe
发布于 2017/08/12 23:39
字数 1605
阅读 59
收藏 0

lvalue

The following expressions are lvalue expressions:

  • 在一个作用域中的变量(variable),无论它是什么类型. 即使该变量(variable)的类型是一个 rvalue reference(右值引用, 比如 int&& number{10};)它都是 lvalue.
  • 通常情况下: 一个函数调用(a function call)接受一个lvalue 或者 lvalue的重载操作表达式返回类型都应该是一个lvalue.  例如:std::getline(std::cin, str), std::cout << 1, str1 = str2, or ++it;
  • a = b, a += b, a %= b ...等等内置的赋值(assignment)/复合赋值操作(compound assignment)都是lvalue expression,结果也都是 lvalue.
  • ++a and --a 等等内置的前置递增操作都是lvalue expression, 结果也都是lvalue.
  • *p, 内置的从指针的取值操作也是 lvalue expression,结果也是lvalue.
  • a[n] and p[n], 内置的 subscript(下标操作表达式) , a是一个数组的lvalue, p是一个指向数组的指针,这种情况下结果也是lvalue;
  • a.m,the member of object expression的结果为lvalue,  当a 是一个class/struct object的lvalue/lvalue reference; m是一个member data(non-static)/member function(返回一个reference type).
  • a.*mp,  pointer to member of object expression的,  当a是一个class/struct object的lvalue/lvalue reference; mp为一个指针 指向class/struct member data(non-static)/member function(返回一个reference type).
  • p->*mp,  pointer to member of pointer expression的结果为lvalue,  mp应该为一个指针 指向class/struct member data(non-static)/member function(返回一个reference type).
  • (a, b), comma expression(逗号表达式), 当b为lvalue的时候该表达式(expression)的结果为lvalue;
  • a ? b : c, ternary conditional expression(三元表达式),如果b, c为lvalue那么结果为lvalue.;
  • a cast expression to lvalue reference type, such as static_cast<int&>(x);
  • a function call or an overloaded operator expression of rvalue reference to function return type;
  • a cast expression to rvalue reference to function type, such as static_cast<void (&&)(int)>(x).
(since C++11)

Properties:

  • Same as glvalue (below).
  • 取lvalue的地址例如: &++i[1] and &std::endl都是有效的.
  • 一个可修改的lvalue可被用于左操作数(left-hand-operand).
  • lvalue可被用于初始化另外一个lvalue(术语叫做:  the object identified by the expression).

 

 

prvalue(pure-rvalue)

The following expressions are prvalue expressions:

  • a literal (except for string literal), such as 42, true or nullptr(这里重点说明: "shihua"的类型为 const char(&)[4]是个lvalue.);
  • 函数调用(a function call) 或者 重载操作的表达式( an overloaded operator expression), 他们的返回值都不是引用(reference), 例如 str.substr(1, 2), str1 + str2, or it++;
  • a++ and a--, 内置的(built-in)后置递增递减 (post-increment and post-decrement) expressions,结果也都是prvalue.
  • a + b, a % b, a & b, a << b, 等等内置的算术表达式(and all other built-in arithmetic expressions)结果都为prvalue;
  • a && b, a || b, !a, 内置的逻辑表达式(the built-in logical expressions)结果都为prvalue;
  • a < b, a == b, a >= b, 等等其他的内置的比较表达式(and all other built-in comparison expressions)结果都为prvalue;
  • &a, 内置的取地址操作(the built-in address-of expression)结果也是一个prvalue;
  • a.m, the member of object expression, 当a为一个prvalue, m为 non-static member function的时候且该member function不返回reference type.
  • p->m, (the built-in member of pointer expression)通过class/struct object的指针调用member function(non-static)的情况, 该member function可能返回一个对member function内变量/class内部member data的copy 这种情况下结果为prvalue.
  • a.*mp, (the pointer to member of object expression)通过class/struct object调用member function(non-static)的情况, 该member function可能返回一个对member function内变量/class内部member data的copy 这种情况下结果为prvalue.
  • p->*mp, (the built-in pointer to member of pointer expression)通过class/struct object的指针调用member function(non-static)的情况, 该member function可能返回一个对member function内变量/class内部member data的copy 这种情况下结果为prvalue.
  • (a, b),内置的逗号表达式( the built-in comma expression), 当b为一个prvalue的时候结果也为prvalue;
  • (a ? b : c), 三元表达式(the ternary conditional expression)当 a 和 b都为prvalue的时候结果必定为prvalue.;
  • 一个转换表达式(a cast expression)转为非引用类型 , 例如:static_cast<double>(x), std::string{}, or (int)42 结果为prvalue;
  • this指针(the this pointer);
(since C++11)
  • a requires-expression, such as requires (T i) { typename T::type; }
  • a specialization of a concept, such as EqualityComparable<int>
(since C++20)

Properties:

  • Same as rvalue (below).
  • 一个prvalue不能是多态的( polymorphic).
  • 一个不是clss/struct和数组的prvalue不能使用const/volatile修饰.例如:  volitle int{ 20}; const int{ 20 };都是错误的.
  • 一个prvalue不能是incomplete type (except for type void).

 

xvalue

The following expressions are xvalue expressions:

  • 函数或者 一个重载操作表达式(a function call or an overloaded operator expression) 返回类型为Type&&. 例如: std::move(x)返回结果就是一个xvalue.
  • a[n], 内置的数组下标操作( the built-in subscript expression),例如:struct foo { int a[3]; };
    foo() /* prvalue */ .a[3] /* xvalue */;  struct Test{ int number};  Test{}.number;/*xvalue*/.
  • a.m, the member of object expression, 当a为一个rvalue(注意不是prvalue)的时候,m为一个 non-static的member data;
  • a.*mp, the pointer to member of object expression, 当a为一个rvalue, mp是一个指向该class/struct 的 non-static 的 member data.
  • a ? b : c, the ternary conditional expression, 例如: struct Test{ int number };  false/true ?Test{}.number : Test{}.number;
  • a cast expression to rvalue reference to object type, 例如: static_cast<char&&>(x); x必须为lvalue.
(since C++17)

Properties:

  • Same as rvalue (below).
  • Same as glvalue (below).

总结, xvalues一般都是绑定到 rvalue references, xvalues可以是多态的(ploymorphic), 非class/struct类型的xvalues可以是 cv-qualified的(const/volitale修饰).

 

 

 

glvalue

A glvalue expression is either lvalue or xvalue.

Properties:

  • A glvalue may be implicitly converted to a prvalue with lvalue-to-rvalue, array-to-pointer, or function-to-pointer implicit conversion.
  • A glvalue may be polymorphic: the dynamic type of the object it identifies is not necessarily the static type of the expression.
  • A glvalue can have incomplete type, where permitted by the expression.

rvalue

An rvalue expression is either prvalue or xvalue.

Properties:

  • Address of an rvalue may not be taken: &int(), &i++[3], &42, and &std::move(x) are invalid.
  • An rvalue can't be used as the left-hand operand of the built-in assignment or compound assignment operators.
  • An rvalue may be used to initialize a const lvalue reference, in which case the lifetime of the object identified by the rvalue is extended until the scope of the reference ends.
  • An rvalue may be used to initialize an rvalue reference, in which case the lifetime of the object identified by the rvalue is extended until the scope of the reference ends.
  • When used as a function argument and when two overloads of the function are available, one taking rvalue reference parameter and the other taking lvalue reference to const parameter, an rvalue binds to the rvalue reference overload (thus, if both copy and move constructors are available, an rvalue argument invokes the move constructor, and likewise with copy and move assignment operators).

 

© 著作权归作者所有

SHIHUAMarryMe
粉丝 13
博文 162
码字总数 138435
作品 0
武汉
程序员
私信 提问
SonarQube C/C++/Objective-C 4.2 发布

SonarQube C/C++/Objective-C 4.2 发布了,这是一个C/C++/Objective-C的插件,用于检查代码质量。 这个版本提供了以下的新规则: “nonnull” pointers should not be set to null (C, Bug) ...

局长
2016/10/06
1K
0
C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast

C++强制类型转换:staticcast、dynamiccast、constcast、reinterpretcast 1. c强制转换与c++强制转换 c语言强制类型转换主要用于基础的数据类型间的转换,语法为: (type-id)expression//转换...

shzwork
03/12
3
0
C/C++ 之 C++强制类型转换(static_cast、dynamic_cast、const_cast、reinterpret_cast)

文章转载自:https://www.cnblogs.com/chenyangchun/p/6795923.html 。在了解这块时,发现了这篇文档,感觉写的很不错! c强制转换与c++强制转换 c 语言强制类型转换主要用于基础的数据类型间...

ZCShouCSDN
2018/12/19
0
0
C++各阶段学习书目

1. 入门 Lippman的《Essential C++》 顾名思义,这本书是很短小精悍的。通过这本书,可以对C++的最常用和重要的特性有全面的了解,并对C++的全貌有一个概念。虽然这远远不够,但就是这样的书...

晨曦之光
2012/04/24
440
1
001-EMC 深入解读-目录

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q1007729991/article/details/82717008 除了刚毕业的应届生,从来没人敢说他精通 C++,Bjarne Stroustrup (C...

--Allen--
2018/09/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

rime设置为默认简体

转载 https://github.com/ModerRAS/ModerRAS.github.io/blob/master/_posts/2018-11-07-rime%E8%AE%BE%E7%BD%AE%E4%B8%BA%E9%BB%98%E8%AE%A4%E7%AE%80%E4%BD%93.md 写在开始 我的Arch Linux上......

zhenruyan
今天
5
0
简述TCP的流量控制与拥塞控制

1. TCP流量控制 流量控制就是让发送方的发送速率不要太快,要让接收方来的及接收。 原理是通过确认报文中窗口字段来控制发送方的发送速率,发送方的发送窗口大小不能超过接收方给出窗口大小。...

鏡花水月
今天
10
0
OSChina 周日乱弹 —— 别问,问就是没空

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :#今日歌曲推荐# 分享容祖儿/彭羚的单曲《心淡》: 《心淡》- 容祖儿/彭羚 手机党少年们想听歌,请使劲儿戳(这里) @wqp0010 :周...

小小编辑
今天
1K
11
golang微服务框架go-micro 入门笔记2.1 micro工具之micro api

micro api micro 功能非常强大,本文将详细阐述micro api 命令行的功能 重要的事情说3次 本文全部代码https://idea.techidea8.com/open/idea.shtml?id=6 本文全部代码https://idea.techidea8....

非正式解决方案
今天
5
0
Spring Context 你真的懂了吗

今天介绍一下大家常见的一个单词 context 应该怎么去理解,正确的理解它有助于我们学习 spring 以及计算机系统中的其他知识。 1. context 是什么 我们经常在编程中见到 context 这个单词,当...

Java知其所以然
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部