Effective C++: expression value category

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)
(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).

 

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/1507242

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值