程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> [C/C++不常見語法特性]_[初級]_[左值-右值-lvalue-rvalue]

[C/C++不常見語法特性]_[初級]_[左值-右值-lvalue-rvalue]

編輯:C++入門知識

[C/C++不常見語法特性]_[初級]_[左值-右值-lvalue-rvalue]


參考:
1. http://en.cppreference.com/w/cpp/language/value_category
<< Value categories >>
2. https://msdn.microsoft.com/en-us/library/dd293668.aspx
<< Rvalue Reference Declarator: && >>
3. https://msdn.microsoft.com/en-us/library/f90831hc.aspx
<< Lvalues and Rvalues (Visual C++) >>
4. << Working Draft, Standard for Programming Language C ++ >> [Document Number: N3797]
3.10 Lvalues and rvalues
5. http://en.cppreference.com/w/cpp/utility/move
<< std::move >>

場景:
1. C++11 引入了std::move,它可以高效率的從一個左值資源移動到另一個左值資源裡,這個過程不需要再創建新的資源. 這對std::string,std::vector這種標准庫的資源操作更加精煉.使用標准庫時會大量使用這個std::move模板函數.


2. 在std::move的源碼裡又涉及到std::remove_reference 模板結構體,這個結構體又涉及到 "右值引用聲明(Rvalue Reference Declarator: &&)", 所以這裡還是講講基本的左值和右值.



左值和右值(Lvalues and rvalues)
1. 這裡的左值和右值可以稱為左值表達式和右值表達式,
因為每個C++表達式要麼是一個左值要麼是一個右值 -- Lvalues and Rvalues (Visual C++).
2. 左值和右值可以細分為以下類型: 圖
glvalue,rvalue,lvalue,xvalue,prvalue
\

左值(lvalue)


lvalue: An lvalue (so called, historically, because lvalues could appear on the left-hand side of an assignment expression) designates a function or an object. [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 result of calling a function whose return type is an lvalue reference is an lvalue. —end example ] -- 3.10 Lvalues and rvalues
左值: 一個左值( 之所以這麼叫是因為歷史原因: 因為這些左值出現在賦值表達式的左邊) 指明了一個函數或者一個對象. [例子: 如果E是一個指針類型的表達式,那麼*E 就是一個引用這個E指針指向的對象或函數的左值表達式. 另一個例子是, 請求一個函數的返回值是一個左值引用就是一個左值]


An lvalue refers to an object that persists beyond a single expression. You can think of an lvalue as an object that has a name. All variables, including nonmodifiable (const) variables -- Lvalues and Rvalues (Visual C++)
一個左值引用了一個對象,這個對象在單個表達式外依舊保持可用. 你可以認為一個左值是一個具有名字的對象.所有變量, 包括不可以修改的(const)變量


An lvalue ("left value") expression is an expression that has identity and cannot be moved from. The naming is historic and reflects the use of lvalue expressions as the left-hand operand of the assignment operator in the CPL programming language. -- Value categories

一個左值表達式 是一種具有id(標識)的,不能被moved from的(即不能被直接move,必須先轉換為右值).左值的命名是歷史的原因,反映了左值表達式作為賦值操作符的左操作數來使用的.

 

右值(rvalue)


rvalue: An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object (12.2) or subobject thereof, or a value that is not associated with an object. -- 3.10 Lvalues and rvalues
一個右值可以是一個xvalue,一個臨時對象或者臨時對象的子對象, 或者一個沒關聯到一個對象的值.


An rvalue is a temporary value that does not persist beyond the expression that uses it. -- Lvalues and Rvalues (Visual C++).
一個右值是一個臨時值,它在表達式外(只有表達式使用這個右值)不再存儲使用.


An rvalue ("right value") expression is an expression that is either a prvalue or an xvalue. It can be moved from. It may or may not have identity -- Value categories

一個右值表達式是一個prvalue或者一個xvalue, 它能被 moved from.

 

xvalue(到期值 expiring value)


An rvalue (so called, historically, because rvalues could appear on the right-hand side of an assignment expression) is an xvalue, a temporary object or subobject thereof, or a value that is not associated with an object. -- 3.10 Lvalues and rvalues

An xvalue ("expiring value") expression is an expression that has identity and can be moved from.

-- Value categories

 

glvalue(廣義左值? "generalized" lvalue)

  A glvalue (“generalized” lvalue) is an lvalue or an xvalue. -- 3.10 Lvalues and rvalues

A glvalue ("generalized lvalue") expression is an expression that is either an lvalue or an xvalue.It has identity. It may or may not be moved from. -- Value categories

A prvalue(純右值)

  (“pure” rvalue) is an rvalue that is not an xvalue. [Example: The result of calling a function whose return type is not a reference is a prvalue. The value of a literal such as 12, 7.3e5, or true is also a prvalue. -- 3.10 Lvalues and rvalues

A prvalue ("pure rvalue") expression is an expression that does not have identity and can be moved from. -- Value categories

摘錄cppreference.com, 判斷左右值的情景:

 

 

The primary value categories correspond to two properties of expressions:

has identity: it's possible to determine whether the expression refers to the same entity as another expression, such as by comparing addresses of the objects or the functions they identify (obtained directly or indirectly); can be moved from:move constructor,move assignment operator, or another function overload that implements move semantics can bind to the expression.

Expressions that:

have identity and cannot be moved from are calledlvalue expressions; have identity and can be moved from are calledxvalue expressions; do not have identity and can be moved from are calledprvalue expressions; do not have identity and cannot be moved from are not used[1].

lvalue

Anlvalue("left value") expression is an expression thathas identityandcannot be moved from. The naming is historic and reflects the use of lvalue expressions as the left-hand operand of the assignment operator in the CPL programming language.

The following expressions are lvalue expressions:

the name of a variable or a function in scope, regardless of type, such asstd::cinorstd::endl. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression; a function call or an overloaded operator expression of lvalue reference return type, such asstd::getline(std::cin, str),std::cout<<1,str1=str2, or++it; a=b,a+=b,a%=b, and all other built-inassignment and compound assignmentexpressions; ++aand--a, the built-inpre-increment and pre-decrementexpressions; *p, the built-inindirectionexpression; a[n]andp[n], the built-insubscriptexpressions, except whereais an array rvalue(since C++11); a.m, themember of objectexpression, except wheremis a member enumerator or a non-static member function, or whereais an rvalue andmis a non-static data member of non-reference type; p->m, the built-inmember of pointerexpression, except wheremis a member enumerator or a non-static member function; a.*mp, thepointer to member of objectexpression, whereais an lvalue andmpis a pointer to data member; p->*mp, the built-inpointer to member of pointerexpression, wherempis a pointer to data member; a, b, the built-incommaexpression, wherebis an lvalue; a?b:c, theternary conditionalexpression for somea,b, andc; astring literal, such as"Hello, world!"; a cast expression to lvalue reference type, such asstatic_cast(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 asstatic_cast(x). (since C++11)

Properties:

Same as glvalue (below). Address of an lvalue may be taken:&++i[2]and&std::endlare valid expressions. A modifiable lvalue may be used as the left-hand operand of the built-in assignment and compound assignment operators. An lvalue may be used toinitialize an lvalue reference; this associates a new name with the object identified by the expression.

rvalue(until C++11)prvalue(since C++11)

Aprvalue("pure rvalue") expression is an expression thatdoes not have identityandcan be moved from.

The following expressions are prvalue expressions:

aliteral(except forstring literal), such as42,trueornullptr; a function call or an overloaded operator expression of non-reference return type, such asstr.substr(1,2),str1+str2, orit++; a++anda--, the built-inpost-increment and post-decrementexpressions; a+b,a%b,a&b,a<arithmeticexpressions; a&&b,a||b,~a, the built-inlogicalexpressions; a=b, and all other built-incomparisonexpressions; &a, the built-inaddress-ofexpression; a.m, themember of objectexpression, wheremis a member enumerator or a non-static member function[3], or whereais an rvalue andmis a non-static data member of non-reference type(until C++11); p->m, the built-inmember of pointerexpression, wheremis a member enumerator or a non-static member function[3]; a.*mp, thepointer to member of objectexpression, wherempis a pointer to member function[3], or whereais an rvalue andmpis a pointer to data member(until C++11); p->*mp, the built-inpointer to member of pointerexpression, wherempis a pointer to member function[3]; a, b, the built-incommaexpression, wherebis an rvalue; a?b:c, theternary conditionalexpression for somea,b, andc; a cast expression to non-reference type, such asstatic_cast(x),std::string{}, or(int)42; alambda expression, such as[](intx){returnx*x;}. (since C++11)

Properties:

Same as rvalue (below). A prvalue cannot bepolymorphic: thedynamic typeof the object it identifies is always the type of the expression. A non-class prvalue cannot becv-qualified. A prvalue cannot haveincomplete type(except for type void, see below, or when used indecltype specifier).

xvalue

Anxvalue("expiring value") expression is an expression thathas identityandcan be moved from.

The following expressions are xvalue expressions:

a function call or an overloaded operator expression of rvalue reference to object return type, such asstd::move(x); a[n], the built-insubscriptexpression, whereais an array rvalue; a.m, themember of objectexpression, whereais an rvalue andmis a non-static data member of non-reference type; a.*mp, thepointer to member of objectexpression, whereais an rvalue andmpis a pointer to data member; a?b:c, theternary conditionalexpression for somea,b, andc; a cast expression to rvalue reference to object type, such asstatic_cast(x).

Properties:

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

Like prvalues, xvalues bind to rvalue references, but unlike prvalues, an xvalue may bepolymorphic, and a non-class xvalue may becv-qualified.

(since C++11)

Mixed categories

glvalue

Aglvalue("generalized lvalue") expression is an expression that is either an lvalue or an xvalue. Ithas identity. It may or may not be moved from.

Properties (note: these apply to pre-C++11 lvalues as well):

A glvalue may be implicitly converted to a prvalue with lvalue-to-rvalue, array-to-pointer, or function-to-pointerimplicit conversion. A glvalue may bepolymorphic: thedynamic typeof the object it identifies is not necessarily the static type of the expression. A glvalue can haveincomplete type, where permitted by the expression.

rvalue

Anrvalue("right value") expression is an expression that is either a prvalue or an xvalue. Itcan be moved from. It may or may not have identity. The naming is historic and reflects the use of rvalue expressions as the right-hand operand of the assignment operator in the CPL programming language.

Properties (note: these apply to pre-C++11 rvalues as well):

Address of an rvalue may not be taken:&int(),&i++[4],&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 toinitialize 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 toinitialize 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 whentwo overloadsof 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 themove constructor, and likewise with copy and move assignment operators). (since C++11)
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved