Summary of lvalues, rvalues, lvalue references, and rvalue references


In C language we often mention lvalue (lvalue) and rvalue (rvalue). When the compiler reports an error when compiling a program, it sometimes reports that the error message contains lvalues ​​and rvalues. But there is no strict definition of lvalue and rvalue. Most of the time, the definition of left and right values ​​​​and their identification methods are integrated.
A typical judgment method is in the assignment expression. What appears to the left of the equal sign is 左值 , and the one on the right side of the equal sign is called 右值 .
For example:
a = b + c;
In this assignment expression, a is an lvalue, and b+c is an rvalue. This method of identifying lvalues ​​and rvalues ​​is still valid in C++.
However, there is another widely recognized statement in C++, that is Things that can take addresses and have names are lvalues , and vice versa, Things that cannot take addresses and have no names are rvalues .
In this assignment expression, &a is the operation that is run. But operations like &(b+c) will not compile. Therefore a is an lvalue and (b+c) is an rvalue.

What is an lvalue

Yes and according to C++: anything that can take an address and has a name is an lvalue.

What is an rvalue

cannot take the address and does not have a name, it is an rvalue. Specifically in C++11, rvalue is composed of two concepts.
One is checkmate value. One is a prvalue.

Primal rvalues:

Pure rvalue (prvalue, Pure Rvalue) is the rvalue concept in the C++98 standard, such as the temporary variable value returned by a function. There are also some operation expressions, such as the temporary variable value generated by 1 + 3.
Literal value not associated with an object, such as: 2, ‘c’, true. lambda expression . They are all pure rvalues.

Checkmate value:

Expiring value (xvalue, eXpiring) is a new expression related to rvalue reference in C++11. Such an expression is usually the object to be moved (moved to another use).
For example: the return value of the function that returns an rvalue reference T&&; the return value of std::move; the return value of the type conversion function that converts to T&&.

: In C++11 programs, all values ​​must belong to one of the three categories: lvalue, dying value, and pure rvalue.

lvalue reference

An lvalue reference is the reference T& in C++98. Before C+11 rvalue references came out. The references mentioned all refer to lvalue references.
For example:
int a = 10;
int & b = a;
const int & c = a;
b and c are both lvalue references. b is a non-const lvalue reference. c is a constant lvalue reference.
An lvalue reference, as the name suggests, is a type that references an lvalue. That is, the right side of the equal sign is an lvalue (which can take an address).
The constant lvalue reference type is special and can also reference rvalues. For example, const int &d = 2; but int &d = 2; cannot be compiled.
Therefore, the constant lvalue reference type is also called a universal reference type. The referenced content cannot be modified through a constant lvalue reference. A non-const lvalue reference can modify the referenced content.

rvalue reference

Rvalue reference is a new reference type in C++11. As the name suggests, it is a type that references an rvalue. In fact, since rvalues ​​don't have names. We can only find its existence through references.
For example: T && a = ReturnRvalue();
In this expression, assuming that the ReturnRvalue function returns an rvalue, we declare a name It is an rvalue reference of a, and its value is equal to the value of the temporary variable returned by the ReturnRvalue function.
注意: T&& is the type of rvalue reference. Compared with lvalue references, there is an extra & symbol. It is different from the use of secondary pointers. Second-level references do not exist on C++.
注意: Reference is also a variable, but it is a special variable with its own type.
相同点:
Both lvalue references and rvalue references belong to reference types.
Whether an lvalue reference or an rvalue reference is declared, it must be initialized immediately. The reason can be understood as that the reference type itself does not own the memory of the bound object. It is just an alias of the object and takes up almost no memory. : An lvalue reference is an alias for a named variable value, while an rvalue reference is an alias for an unnamed (anonymous) variable. An rvalue reference cannot be bound to any lvalue. For example: int c; int && d = c;//It does not compile but relative lvalue reference It cannot be bound to an rvalue (initialized by an rvalue). For example: T & e = ReturnRvalue();//Cannot compile. But there is an exception: const T & e = ReturnRvalue();//Compilation passes. Above we said that a constant lvalue reference is a universal reference type, which can receive non-const lvalues ​​(such as int c), constant lvalues ​​(such as const int c), and rvalues. Perform initialization. Usage scenarios of rvalue reference types: the formal parameter types used for move constructors are closely related to move semantics.

不同点









Guess you like

Origin blog.csdn.net/adminstate/article/details/134876604