[C + +] lvalue and rvalue, lvalue reference (&) and rvalue reference (& &)

Keywords: C++

1, C + + lvalues and rvalues

In C + + or C language, an expression (which can be literal quantity, variable, object, return value of function, etc.) is divided into lvalue expression and rvalue expression according to its use scenario. To be exact, the concepts of left value and right value in C + + are inherited from C language.

The English abbreviation of the left value is "lvalue", and the English abbreviation of the right value is "rvalue". Many people think they are abbreviations of "left value" and "right value", but they are not. Lvalue is the abbreviation of "loader value", which can mean data stored in memory with explicit storage address (addressable), while rvalue is translated as "read value", which refers to data that can provide data value (not necessarily addressable, such as data stored in registers).

How to judge whether an expression is an lvalue or an lvalue:

① The expression that can be located to the left of the assignment number (=) is the lvalue; Conversely, an expression that can only be located to the right of the assignment number is an R-value.

int a = 5;
5 = a; //Error, 5 cannot be an lvalue

/*
Where a is an lvalue and literal 5 is an lvalue
*/

[note] the left value in C + + can also be used as the right value.

int b = 10; // b is an lvalue
a = b; // a. b is an lvalue, but b can be used as an lvalue

  ② The named expression that can obtain the storage address is the lvalue; Otherwise, it is the right value.

  In the above example, variables A and b are variable names, and their storage addresses can be obtained through & A and & b, so both a and b are lvalues; On the contrary, literal quantities 5 and 10 have neither name nor storage address (literal quantities are usually stored in registers or together with code), so 5 and 10 are right values.

 

  2, Right value reference

1. Introduction of right value reference

There was a reference "&" before C++11, but this reference has a defect, that is, under normal circumstances, it can only operate the left value in C + + and cannot add a reference to the right value.

int num = 10;
int &b = num; //correct
int &c = 10; //error

The compiler allows us to create a reference for the left value of num, but not for the right value of 10.

The reference represented by "&" is also called lvalue reference.

[note] although the C++98/03 Standard does not support the establishment of non constant lvalue references for right values, constant lvalue references are allowed to operate right values. That is, constant lvalue references can operate on both lvalues and lvalues.

int num = 10;
const int &b = num;
const int &c = 10;

The right value often has no name, so it can only be used by reference. This leads to a problem. In actual development, we may need to modify the right value (required when implementing mobile semantics). Obviously, the way of lvalue reference is not feasible.

Therefore, C++11 standard introduces another reference method, called right value reference, which is represented by "& &".

2. Use of right value reference

①   Like declaring an lvalue reference, an lvalue reference must be initialized immediately and can only be initialized with an lvalue.

int num = 10;
//int && a = num;  // An rvalue reference cannot be initialized to an lvalue
int && a = 10;

②   The right value reference can modify the right value

int && a = 10;
a = 11;
cout << a << endl;   //The output is 11

③ C + + syntax word definition constant right value reference

const int&& a = 10;//The compiler does not report an error

However, this form of right value reference is of no practical use. On the one hand, R-value reference is mainly used for mobile semantics and perfect forwarding. The former needs permission to modify R-value; Secondly, the function of constant R-value reference is to reference an unmodifiable R-value, which can be completed by constant l-value reference.

[summary]

① Non constant lvalue references can reference only non constant lvalues. Constant lvalues refer to non constant lvalues, constant lvalues and right values

	int num = 10;
	int& a = num;	//Compilation succeeded. Non constant lvalue reference is supported
	const int num2 = 100;
	int& b = num2;	//Compilation failed. Non constant lvalue reference is not supported
	int& c = 10;	//Compilation failed. Reference to right value is not supported for non constant lvalue reference

	const int& d = num;		//Compilation succeeded. Constant lvalue references support referencing non constant lvalues
	const int& e = num2;	//Compilation succeeded. Constant lvalue reference is supported
	const int& f = 100;		//Compilation succeeded. Constant lvalue reference supports reference to lvalue

② Right value reference does not support reference of left value; The non constant right value reference can reference only non constant right values, and the constant right value references non constant right values and constant right values

	int num = 10;
	const int num2 = 100;
	int&& a = num;	//Compilation failed. Non constant right value reference does not support non constant left value reference
	int&& b = num2;	//Compilation failed. Non constant right value reference does not support reference to constant left value
	int&& c =10;	//Compilation succeeded. Non constant right value reference is supported
	const int&& d = num;	//Compilation failed. Constant right value reference does not support reference to non constant left value
	const int&& e = num2;	//Compilation failed, constant right value reference does not support referencing constant left value
	const int&& f = 100;	//Compilation succeeded. Constant R-value reference supports R-value reference

3, The move() function casts an lvalue to an lvalue

Syntax format of move() function:

move(arg)
//agr: lvalue object, which returns the right value form of arg object
	int num = 10;
	int&& a = std::move(num);  //Compilation succeeded
	cout << a << endl;   //The output result is 10;

Posted by Tonka1979 on Wed, 13 Oct 2021 13:47:01 -0700