Lvalue and rvalue in C and C++

A simple definition

This part first gives a simple definition of lvalue and rvalue. The article will be described in detail below.
lvalue (locator value) generation.

Left value, right value

  In C++11, all values ​​must belong to one of the left and right values, and the right values ​​can be subdivided into pure right values ​​and dead values. In C++11, those that can take addresses and have names are lvalues. On the contrary, those that cannot take addresses and have no names are rvalues ​​(death values ​​or pure rvalues). The lvalue represents an object that occupies a certain position in memory (in other words, it has an address). For example, int a = b+c, a is the lvalue, and its variable name is a, which can be obtained by &a The address of the variable; the return value of the expression b+c and function int func() is an rvalue. Before it is assigned to a variable, we can’t find it by the variable name. An operation like &(b+c) Will not compile.

Right value, dead value

  In C++11, rvalues ​​are divided into pure rvalues ​​(prvalue, Pure Rvalue) and xvalues ​​(eXpiring Value). The concept of pure rvalue refers to temporary variables and literal values ​​that are not associated with objects; the dead value is a new expression related to rvalue references in C++11, so that the expression will usually be moved Objects of (moved for other uses), such as the return value of the function that returns the rvalue reference T&&, the return value of std::move, or the return value of the type conversion function converted to T&&.

  The dead value can be understood as the value obtained by "stealing" the memory space of other variables. When ensuring that other variables are no longer used or about to be destroyed, the release and allocation of memory space can be avoided by "stealing", and the lifetime of the variable value can be prolonged.

Lvalue reference, rvalue reference

  An lvalue reference is a type that references an lvalue. An rvalue reference is a type of reference to an rvalue. In fact, since an rvalue usually does not have a name, we can only find its existence by reference.

  Both rvalue references and lvalue references belong to reference types. Whether you declare an lvalue reference or an rvalue reference, you must initialize it immediately. The reason can be understood as that the reference type itself does not own the memory of the bound object, but is just an alias of the object. Lvalue references are aliases for named variable values, and rvalue references are aliases for unnamed (anonymous) variables.

  Lvalue references usually cannot be bound to rvalues, but constant lvalue references are a "universal" reference type. It can accept non-constant lvalue, constant lvalue, and rvalue to initialize it. However, the rvalue referenced by the constant lvalue can only be read-only for the rest of its life. In contrast, a non-constant lvalue can only accept a non-constant lvalue to initialize it.

 

int &a = 2;       # 左值引用绑定到右值,编译失败
int b = 2;        # 非常量左值
const int &c = b; # 常量左值引用绑定到非常量左值,编译通过
const int d = 2;  # 常量左值
const int &e = c; # 常量左值引用绑定到常量左值,编译通过
const int &b =2;  # 常量左值引用绑定到右值,编程通过

  An rvalue reference usually cannot be bound to any lvalue. If you want to bind an lvalue to an rvalue reference, you usually need std::move() to coerce the lvalue into an rvalue, for example:

int a;
int &&r1 = c;             # 编译失败
int &&r2 = std::move(a);  # 编译通过

  The following table lists the types of values ​​that can be referenced by various reference types in C++11. It is worth noting that as long as the reference type of the rvalue can be bound, the life of the rvalue can be extended.

Guess you like

Origin blog.csdn.net/sunlin972913894/article/details/104023377