I'm writing a matrix 3x3 class in c++.
glm::mat3 provides access to matrix data through the [][] operator
syntax.
e.g. myMatrix[0][0] = 1.0f;
would set the first row, first column entry to 1.0f.
I'd like to provide similar access. How can I overload the [][] operator
s?
I've tried the following, but I get errors:
operator name must be declared as a function
const real operator[][](int row, int col) const
{
// should really throw an exception for out of bounds indices
return ((row >= 0 && row <= 2) && (col >= 0 && col <= 2)) ? _data[row][col] : 0.0f;
}
What's the correct way to overload this operator?
The expression
foo[1][2]
is really interpreted as(foo[1])[2]
, i.e. the[]
operator is applied twice in succession starting with the variablefoo
. There is no[][]
operator to be overloaded.There is no operator
[][]
, so you need to overload the[]
operator twice: once on the matrix, returning a surrogate object for the row, and once for the returned surrogate row:It would be easier to make the method
double operator() (int row, int col) const
. Instead ofmatrix[i][j]
you just saymatrix(i,j)
.There is no
[][]
operator. The way GLM does it is by returning avec3&
from the first[]
.vec3
has its own[]
operator overload. So it's two separateoperator[]
s on two separate classes.This is also how GLSL works. The first
[]
gets the column as a vector. The second takes the vector and gets the value from it.Generally, for multiple argument you want to use
operator()
, notoperator[]
.Hm, in case it wasn't obvious, there is no
operator[][]
in C++. It's justoperator[]
applied twice. Which means that if you want that notation, then you have to let the first one return a result (indexable thing or proxy) that the second can be applied to.The code below sketches some approaches, choose what you like:
Oh well I discovered after posting that code that I haven't fully hidden the internal storage for
Mat5
: it needs an extra proxy level, as inMat4
. So that approach is really complex. I wouldn't do it (Mat1
is nice and easy I think), but some folks think proxys are cool, and data hiding even more cool…Summing up, there is no “the” correct way to overload
operator[]
. There are many ways (as illustrated by the code above), each with some trade-offs. And generally you’re better off usingoperator()
, because as opposed tooperator[]
it can take any number of arguments.