3

Possible Duplicate:
Operator[][] overload

I have made class which contains an array containing (in one row) all the numbers from the given 2d array. For example given: {{1,2}{3,4}} the b field in the object of class T contains {1,2,3,4}. I would like to overload[][] operator for this class so it will work like that

T* t.....new etc.
int val = (*t)[i][j]; //I get t->b[i*j + j] b is an 1dimension array

    class T{
    public:
        int* b;
        int m, n;
        T(int** a, int m, int n){
            b = new int[m*n];
            this->m = m;
            this->n = n;
            int counter = 0;
            for(int i  = 0; i < m; i++){
                for(int j = 0; j < n; j++){
                    b[counter] = a[i][j];
                    counter++;
                }
            }
        }
int main()
{
    int m = 3, n = 5, c = 0;
    int** tab = new int*[m];
    for(int i = 0; i < m; i++)
           tab[i] = new int[n];
    for(int i  = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            tab[i][j] = c;
            c++;
            cout<<tab[i][j]<<"\t";
        }
        cout<<"\n";
    }


    T* t = new T(tab,3,5);

    };
Community
  • 1
  • 1
Yoda
  • 17,363
  • 67
  • 204
  • 344

2 Answers2

5

You cannot. You have to overload operator[] to return a proxy object, that in turn, overloads operator[] to return the final value.

Something like:

class TRow
{
public:
    TRow(T &t, int r)
    :m_t(t), m_r(r)
    {}
    int operator[](int c)
    {
        return m_t.tab[m_t.n*m_r + c];
    }
private:
    T &m_t;
    int m_r;
};

class T
{
    friend class TRow;
    /*...*/
public:
    TRow operator[](int r)
    {
         return TRow(*this, r);
    }
};

Instead of saving a T& in TRow you could save directly a pointer to the row, that's up to you.

A nice feature of this solution is that you can use the TRow for other things such as operator int*().

rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • Or you could settle for different syntaxes instead, like `obj(i,j)` or `obj[{i,j}]`. – aschepler Feb 01 '13 at 19:07
  • With that in mind, it's a lot less hassle just write a `get(int,int)` function, or overload `operator()(int,int)`. – Benjamin Lindley Feb 01 '13 at 19:07
  • @BenjaminLindley how to overload() operator, can't find it anywhere – Yoda Feb 01 '13 at 19:18
  • @RobertKilar: I answered a question asked by you, showing how to overload `operator()` [here](http://stackoverflow.com/a/14653048/1629821). – Mr.C64 Feb 01 '13 at 19:21
  • @RobertKilar: I can't follow you... `operator()` doesn't need to be `static`...(?) `operator()` is just a **member function**, than can access non-static fields in your class... Please read the code I posted in the [aforementioned thread](http://stackoverflow.com/a/14653048/1629821), and realize that `operator()` member function can access non-static data members as well. – Mr.C64 Feb 01 '13 at 19:28
2

In the case of a 2d array, you don't need to create a proxy type. Just use int*:

#include <iostream>

class T {
public:
  int m, n;
  int *b;
  T(int m, int n) : m(m), n(n), b(new int[m*n]) {
  }
  int*operator[](std::size_t i) {
    return &b[i*m];
  }
};

int main () {
  T t(2,2);
  t[0][0] = 1;
  t[0][1] = 2;
  t[1][0] = 3;
  t[1][1] = 4;
  std::cout << t.b[0] << t.b[1] << t.b[2] << t.b[3] << "\n";
}
Robᵩ
  • 163,533
  • 20
  • 239
  • 308