Reputation:
Let's say I have this simple container class
class Array{
private:
int m_l{};
int *m_d{};
public:
Array() = default;
Array(int len)
: m_l{len}
{
assert(len >= 0);
if (len > 0)
{
m_d = new int[len]{};
}
}
~Array(){
delete[] m_d;
}
// -------------------------------------------
int& operator[](int i){
assert(i >= 0 && i <= m_l && "Index in operator [] out of range");
return m_d[i];
}
//--------------------------------------------
};
Specifically
int& operator[](int i)
{
assert(i >= 0 && i <= m_l && "Index in operator [] out of range");
return m_d[i];
}
I have overloaded the []
operator to get the subscript, I am just learning about operator overloading and container classes.
Array arr{5};
arr[0] = 32;
arr[1] = 34;
std::cout << arr[0];
32
The code compiles and executes as expected, but if I remove the &
from the function, making it
int operator[](int i)
{
assert(i >= 0 && i <= m_l && "Index in operator [] out of range");
return m_d[i];
}
The compiler throws an error
lvalue required as left of operand assignment
Why does this error occur, what is the significance of &
in the function?
Upvotes: 0
Views: 67
Reputation: 595712
The &
in int&
means that your operator[]
returns a reference (ie, an alias, usually implemented as a memory address) to an int
variable. Once bound to a variable, any value that is assigned to a reference gets assigned to the variable it refers to.
Without the &
, your operator[]
would return a copy (ie, the value) of the int
instead.
When a function returns a value rather than a reference, the compiler creates a temporary variable to hold that value. That temporary exists only until the end of the statement that creates it. That temporary variable is known as an rvalue, ie a value that is used on the right-hand side of an assignment. To preserve the value longer, the caller must assign it to another variable.
Things like named variables, references to variables, etc are lvalues, ie they can used on the left-hand side of an assignment. An rvalue cannot be used on the left-hand side, only on the right-hand side.
Upvotes: 1
Reputation: 598
Without the reference in the subscript operator overload, you are returning a temporary rvalue from the function. An rvalue cannot occur on the left side of an assignment operation.
Specifically, when you write arr[0]
, without the reference in your overload that would just return an integer (as whatever the value of arr[0] is).
Array arr{5};
arr[0]; //Without the reference, this returns 5.
5 = 32; //Written out, this is what the expression turns to.
The 5 is an rvalue that cannot be assigned to - what would 5 = 32
mean? With the reference overload, you are returning a reference (the memory location) to the first element of the array which is an lvalue. Reading this might help you understand it better.
Upvotes: 3