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 `float`

s 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)`

.