E0461 - Initial value of non-const reference must be an lvalue

I encountered this problem while typing code recently, and reviewed the concepts of lvalue, rvalue, and constant reference. Let's take a look at the reason for this error.


1. What is the reason for this error?

#include<iostream>
using namespace std;
void func(int& x)
{
	cout << x << endl;
}

int main()
{
	int num = 10;
	func(num);
	func(10);//本行代码出现错误
	return 0;
}

First of all,When referencing a variable, the referenced object is determined by the address. Because 10 (rvalue) is a literal constant, it usually does not occupy an address in the memory. If the so-called 10 cannot be found, an error will naturally be reported. When we use num to pass parameters, num (lvalue) is a variable and its address can be obtained. You can find num without reporting an error (what is an lvalue and what is an rvalue will be explained below).

2. Solution

1. Solve it through constant reference

The code is as follows (example):

#include<iostream>
using namespace std;
void func(const int& x)
{
	cout << x << endl;
}

int main()
{
	int num = 10;
	//func(num);
	func(10);//不会报错
	return 0;
}

Constant references can support reference rvalues. The const keyword in const int& x = 10; indicates that x is a constant reference, which can be bound to a constant. In this case, the compiler will create a temporary int variable and then bind a to this temporary variable, making this statement legal. In this way, the value of the constant can be accessed through the constant reference, and the constant will not be modified.


3. What are lvalues ​​and rvalues ​​and how to distinguish them

        In C++ all values ​​are either lvalues ​​or rvalues. An lvalue refers to an object that can still exist after the expression ends, while an rvalue refers to a temporary object that no longer exists after the expression ends. Quickly distinguish left and right value methods to determine whether the address can be taken from the expression. If the address can be taken from the expression, it is an lvalue, otherwise it is an rvalue. For example, the following example:

#include<iostream>
using namespace std;
class A
{
public:
	int m_num;
};

A getNum()
{
	return A();//构造一个A对象 以值的方式返回
}

int main()
{
	int a1 = 1;     //a1是左值,1是右值
	int a2 = a1 + 1;//a2是左值,a1+1是右值
	A a = getNum(); //a是左值,getNum()的返回值是右值(返回临时变量)
	return 0;
}

   In this example, the address where a1 can take is an lvalue, and the address where 1 cannot take is an rvalue. a2 can take the address as an lvalue, but a1+1 cannot take the address as an rvalue. getNum() returns a temporary variable (A a = getNum(); after this line of code ends, the object returned by getNum() will be destroyed, and the address cannot be taken, it is an rvalue.)


Summarize

This article briefly introduces the causes and solutions of the E0461 error. Hope it helps everyone.

Guess you like

Origin blog.csdn.net/m0_74058637/article/details/134624080