14

I am writing a matrix class in c++ and trying to overload some operator like = and >> and << etc.

I was unable to overload operator [][] for matrix class. if i have an object of class matrix like M1 then i can use this way for giving value to each element:

M1[1][2]=5;

OR

int X;

X=M1[4][5];
Tomer
  • 531
  • 7
  • 19
fafa
  • 539
  • 2
  • 7
  • 8

8 Answers8

23

Just overload operator[] and make it return a pointer to the respective row or column of the matrix. Since pointers support subscripting by [], access by the 'double-square' notation [][] is possible then.

You can also overload operator() with two arguments.

Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122
12

There is no operator[][] in C++. You have to return a helper object and then overload operator[] for that too, to have this kind of access.

sudo make install
  • 5,629
  • 3
  • 36
  • 48
RedX
  • 14,749
  • 1
  • 53
  • 76
9

You could overload operator[]. So if you would like to use matrix that way, you should make matrix as array of vectors.

class Matrix
{
...
  Vector & operator[]( int index );
...
};

and

class Vector
{
...
  double & operator[]( int index );
...
};

Finally:

Matrix m;
...
double value = m[i][j];
...
Naszta
  • 7,560
  • 2
  • 33
  • 49
5

there is no operator[][], you can implement operator[] to return a reference to the row/column object, in which you can implement the operator[] to return you the cell reference.

You can do something like the following to avoid all that hassle..

struct loc
{
  int x;
  int y;
};

then in your operator[] overload, accept a loc, something like

T& operator[](loc const& cLoc)
{
 // now you have x/y you can return the object there.
}

To call, you can simply do something like:

matrix[loc(2,3)] = 5; 
Nim
  • 33,299
  • 2
  • 62
  • 101
3

Actually, I did just that in my own matrix class a few years ago. In this case, I defined a matrix template class that contained the snippet, below.

I was then able to iterate and assign as follows:

          for(size_t k=1; k<n; ++k) {       
                   minor[p][k-1]=major[j][k];        
           }

I hope this helps.

// //////////////////////////////////////////////////////////////////////////////
// list is internal vector representation of n x m matrix
T* list;
// Proxy object used to provide the column operator
template < typename T >
class OperatorBracketHelper
{
    Matrix < T > & parent ;
    size_t firstIndex ;

    public :
        OperatorBracketHelper ( Matrix < T > & Parent , size_t FirstIndex ) : 
        parent ( Parent ), firstIndex ( FirstIndex ) {}

        // method called for column operator
        T & operator []( size_t SecondIndex )
        {
            // Call the parent GetElement method which will actually retrieve the element
            return parent.GetElement ( firstIndex , SecondIndex );
        }
};

// method called for row operator
OperatorBracketHelper < T > operator []( size_t FirstIndex )
{
    // Return a proxy object that "knows" to which container it has to ask the element
    // and which is the first index (specified in this call)
    return OperatorBracketHelper < T >(* this , FirstIndex );
}

T & GetElement ( size_t FirstIndex , size_t SecondIndex )
{
    return list[FirstIndex*cols+SecondIndex];
}
user3716429
  • 31
  • 1
  • 1
2

I am exactly working on a matrix class and I decided to first create an Array class which has a dynamic 2-D array. So, well just as you, I confronted this obstacle that how I can overload two square brackets. How I approached this case is very simple; I overloaded the square brackets operator twice as member functions. First, I overloaded [] so as to return a pointer pointing to the desired row, so to speak, and then the following member function (i.e. again operator [] overloaded) returns a lvalue of the same type as the array's elements.

However, note that the index you inter to invoke the former overloaded operator [] must be saved somewhere so that you may use it in the latter overloaded operator []. For this reason I simply added a new member of the type int to the class Array (which I've named it "test" in my code below).

class Array {

private: 

 double **ptr; int test;
 ...   /* the rest of the members includes the number of rows and columns */

public:
    Array(int=3,int=3);  // Constructor
    Array(Array &);      // Copy Constructor
    ~Array();            // Destructor
    void get_array();
    void show_array();
    double* operator[] (int);
    double operator[] (short int);
    ...
};

... 

double* Array::operator[] (int a) {
    test = a;
    double* p = ptr[test];
    return p;
}

double Array::operator[] (short int b) {
   return ((*this)[test][b]);
}

Therefor, as an example, in main I can simply write:

int main(){
Array example;
cout << example[1][2];  
}

I hope this would help you.

0

Template matrix class

template <uint8_t rows, uint8_t cols, typename T>
class MatrixMxN {
public:
    T* operator[](uint8_t f_row) {
        return &m_val[f_row * cols];
    }
protected:
    T m_val[rows*cols];
};

and here is object of matrix with 3 row, 4 column and integer type.

MatrixMxN<3, 4, int32_t> M;
M[2][3] = 10;
std::cout << M[2][3] << std::endl;
C_Raj
  • 162
  • 7
0

You can't overload [][] as such, since there isn't such an operator. You can overload [] to return something which also has an [] defined on it (a proxy); in the simplest case, something like a double* will work, but it's usually better, although a bit more work, to use a full class. (Place to add bounds checking, for example.)

Alternatively, you can overload (x,y). Depending on who you ask, one format or the other is "better". (In fact, it's strictly a question of style.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329