7

it is possible to overload somehow operator for multidimensional array?

Something like:

class A {
  ...
  int& operator[][] (const int x, const int y);
  ...
}
hello_there_andy
  • 2,039
  • 2
  • 21
  • 51
graywolf
  • 7,092
  • 7
  • 53
  • 77
  • Does this answer your question? [Operator\[\]\[\] overload](https://stackoverflow.com/questions/6969881/operator-overload) –  Aug 20 '20 at 23:19

8 Answers8

12

Nope, that is not possible. There are two alternatives, though:

You can have operator[] return an array of a smaller dimension (For a 3D array, it will return a 2D array, for a 2D array it will return a 1D array, and for a 1D array, it will return a single element). Then you can "string them together" with the syntax you want. (arr[x][y][z])

Alternatively, you can overload operator(), because that can take multiple arguments.

Then you can use it like this, to index into a 3D array for example: arr(x,y,z)

But you can't overload [][] or [][][] as a single operator.

jalf
  • 243,077
  • 51
  • 345
  • 550
4

Not directly, but you can achieve the same functionality overloading operator[]() and having it return something that supports operator[]() itself.

For example:

class A {
  std::vector<std::vector<int> > vec;
public:
  std::vector<int>& operator[] (int x)
  {
      return vec[x];
  }
};

would allow you to write:

A a;
//...
int y = a[1][2];

because a[1] returns a std::vector<int> to which you can apply operator[](2).

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Only problem here (in the general case) is that there is no protection against reading off the end of an array. So, if my array is of length 4 and I do a[3][2], I'd overflow on the second operator. – iheanyi May 21 '14 at 17:42
  • @iheanyi that's actually expected, even for a `std::vector`. If you want protection, use `.at` which throws an exception. – Luchian Grigore May 21 '14 at 18:57
  • That's why I said general case. If I had my own array that I wanted to access in this way, and I couldn't use vector (or something similar - so just a normal array), there's no built in protection with your example. – iheanyi May 21 '14 at 19:16
2

You need to overload operator[] and make it return a new class which only has another operator[].

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
2

No, there's just operator[]. As an alternative, you can overload:

int &operator()(int x, int y);

You can use that:

m(4, 5);
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
2

Since C++23, an overloaded operator[] will now take 0 or more arguments which behaves exactly the same as operator()

class A {
  // ...
  int& operator[](std::size_t x, std::size_t j);
  // ...
};

invocation:

A a = /* ... */;

a[1, 2]; // equivalent to 'a.operator[](1, 2)'
Desmond Gold
  • 1,517
  • 1
  • 7
  • 19
0

It is a single operator being used twice to dereference. You can dereference [] operator and perform the functionality and usage by using it as [][] by changing the return type.

Coding Mash
  • 3,338
  • 5
  • 24
  • 45
0

There's no operator like that. I implemented, some times ago, a matrix trying to be close to the stl standards. And I used this method: first I've overloaded the operator[] to return another class that I called _C_row:

_C_row operator[](size_type index) { return _C_row(/*some parameters*/); } ///< This operator is overloaded to permit the use of double pointer notation.
_C_row operator[](size_type index) const { return _C_row(/*some parameters*/); } ///< This operator is overloaded to permit the use of double pointer notation.

And in _C_row I overloaded more than the operator[]:

value_type operator*() { return _r[0]; }
pointer operator->() { return _i[_idx]; }
double_pointer operator&() { return &(_i[_idx]); }
reference operator[](size_type col) { return _r[col]; }
const_reference operator[](size_type col) const { return _r[col]; }

I found this solution is very flexible. I hope my answer could be useful for you.

mik
  • 39
  • 3
0

As mentionned before, there is no such thing as operator[][]. However, here is an an implementation using nested classes similar to what "jalf" proposed. For sake of simplicity, I hardcoded a 3x3 raw array.

    class Array2D final{
    public:
        class PartialArr final{
    private:
        friend Array2D;
        PartialArr(Array2D* ptr, int index) :original(ptr), firstIndex(index) {}
        int firstIndex;
        Array2D* original;
    public:
        int& operator[](int index) { return this->original->data[firstIndex][index];  }
    };

        PartialArr operator[](int index) { return PartialArr(this, index); }
    private:
        int data[3][3];
    };

This solution prevents the user of Array2D to manipulate the data directly when indexing only the first dimension of the array.

const versions of both operator[] could also be added to make the class complete.

melansp
  • 16
  • 1