C++ - lvalue required as left operand of assignment

2.3k Views Asked by At

Consider the following code:

#include <iostream>
using namespace std;

class X 
{
    int i;
public:  
    X(int ii = 0);
};

X::X(int ii) { i = ii; }

int a;

X f1() { return X(); }
int f2() { return a; }

int main() {
    f1() = X(1);
    f2() = 3;
} 

If you try to run it, you get

error: lvalue required as left operand of assignment

on line 17, therefore

f1()

is considered a lvalue, while

f2()

is not. An explanation would be of great help of how things work would be of great help.

2

There are 2 best solutions below

0
On BEST ANSWER

f1() is considered a lvalue

No, what f1 returns is still an rvalue (same as f2; more precisely it's a prvalue). But for class type, f1() = X(1); is just interpreted as f1().operator=(X(1));, which is pretty fine even though it might not make much sense; the temporary object returned by f1() will be destroyed soon. In short, you could call member functions on an rvalue with class type.

On the other hand, the similar behavior for built-in type is forbidden directly; assignment to such temporary doesn't make sense at all. That's why the compiler complains that it's not an lvalue.

1
On

f1() returns an rvalue. You have to return a reference (lvalue) to allow you to do this assignment

Change

int f2() { return a; }

to

int& f2() {  return a; }
   ^

f1() returns rvalue but as instance of class f1() = X(1); calls assignment operator of class f1().operator=(X(1)); which is alright.

Read more about value categories here.