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