lvalue required as left operand of assignment – Array

The error is actually “lvalue required as left operand of assignment”.

It means that your a[i][j] is giving you a temporary object. This happens when you return from a function by value. A function call that returns by value is an rvalue expression, and you cannot use an rvalue expression as the left operand of an assignment. You need to change the implementation of operator[] on both the Matrix and the helper class that Matrix::operator[] returns so that they return by reference. A function call that returns by reference is an lvalue expression and will allow you to assign to it.

template <typename T>
Vector<T>& Matrix<T>::operator[](int index) { ... }
template <typename T>
T& Vector<T>::operator[](int index) { ... }

Of course, this makes sense. If your operator[]s didn’t return by reference, how would assigning to the value returned by them have any effect on the contents of the Matrix?


In response to your edit:

You have a problem with the design of your class. The Matrix class appears to store a 3-by-3 array of floats called coords. However, when you use Matrix::operator[], it copies the values from a row of coords into a Vector object. They are copies. You then return that Vector by value, which copies the Vector and its contained values out of the function. Anything you do to that returned Vector will only affect that copy.

In addition to this, your switch statement is totally pointless. Every case is exactly the same. You just need to use i as the array indices and not switch on it.

Also, if you’re going to allow people that call operator[] to modify the contents of your Matrix, then the operator[] function must not be const.

There are a few alternatives that will fix your problem. The first is to just return a float* instead and scrap your plan with Vector:

float* Matrix::operator[](int i) {
    return coords[i];
}

That’s a very simple solution but does involve passing a raw pointer around. The raw pointer can be used like an array, allowing you the syntax m[i][j].

You could do the same as the Eigen library and instead provide a operator() that takes two arguments, the row index and column index:

float& Matrix::operator()(int i, int j) {
    return coords[i][j];
}

Note that the float is being returned by reference: float&. This means that is modifiable from outside the call to operator(). Here, you would index a row and column with m(i, j).

Leave a Comment