lvalue
The following expressions are lvalue expressions:express
- 在一個做用域中的變量(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:c#
- 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);
- a requires-expression, such as requires (T i) { typename T::type; }
- a specialization of a concept, such as EqualityComparable<int>
|
(since C++20) |
Properties:ide
- 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.
Properties:post
- Same as rvalue (below).
- Same as glvalue (below).
總結, xvalues通常都是綁定到 rvalue references, xvalues能夠是多態的(ploymorphic), 非class/struct類型的xvalues能夠是 cv-qualified的(const/volitale修飾).ui
glvalue
A glvalue expression is either lvalue or xvalue.this
Properties:spa
- 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).
|