5

The question is whether it is possible to overload [ ][ ] .

Well in normal circumstances like vector< vector < int > > , we are overloading the [ ] opertor .

But in cases where if define a special meaning to [ ][ ] is it possible to have such an operator

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Anil Shanbhag
  • 950
  • 1
  • 13
  • 31

5 Answers5

17

There is no special [][] operator; it's operator[] applied to the result of another operator [].

You can give special meaning to [][] construct by having the first operator returning a special temporary object, which also has [] operator.

hamstergene
  • 24,039
  • 5
  • 57
  • 72
12

No, you will have to overload [] to return a value which itself has [] overloaded.

Puppy
  • 144,682
  • 38
  • 256
  • 465
4

As others have pointed out, there is no [][] operator, it's a [] operator applied to the results of a [] operator. In the most general case, the first [] operator will return a proxy, which implements itself a [] operator. In the simplest case, the “proxy” can be a T*, since in C++, pointers implement the [] operator. A more generic implementation might be along the lines of:

class ElementProxy
{
    Container* myOwner;
    int myRowIndex;
    int myColumnIndex;
public:
    ElementProxy( Container* owner, int rowIndex, int columnIndex )
        : myOwner( owner )
        , myRowIndex( rowIndex )
        , myColumnIndex( columnIndex )
    {
    }

    operator Type() const  //  lvalue to rvalue conversion
    {
        return myOwner->get( myRowIndex, myColumnIndex );
    }

    void operator=( Type const& rhs ) const
    {
        myOwner->set( myRowIndex, myColumnIndex, rhs );
    }
};

class RowProxy
{
public:
    RowProxy( Container* owner, int rowIndex )
        : myOwner( owner )
        , myRowIndex( rowIndex )
    {
    }
    ElementProxy operator[]( int columnIndex ) const
    {
        return ElementProxy( myOwner, myRowIndex, columnIndex );
    }
};

This isn't perfect; if you are dealing with class types, it's impossible to support something line container[i][j].x, for example; we can't overload operator.. If you need to support this, about the best you can do is overload operator-> on the ElementProxy, and require client code to use -> instead of ., even though it's not really a pointer, smart or otherwise.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • +1 for the effort of writing so much, illustrating it with an example. :-) – Nawaz Aug 16 '11 at 11:00
  • By the way, why is it `impossible to support something like container[i][j].x`? I think we can. In your code, `ElementProxy` is not needed. Instead if `RowProxy` defines a member `value_type row*`, then `operator[]` can simply do this : `return row[columnIndex];`. In this way one would able to write `container[i][j].x`. – Nawaz Aug 16 '11 at 11:09
  • @Nawaz If you use `value_type*` as the element proxy, there's no problem. Suppose, however, you're implementing some sort of sparse matrix, where you don't have complete rows in the form of a C style (sub-)vector. Or simply where you want to do bounds checking on both the row and the column index. Once you need a class type for the element proxy, you're stuck; `operator.` won't work. – James Kanze Aug 16 '11 at 14:53
  • Bounds checking can be done even with this approach I suggested. As for sparse matrix, that is a special case, and also I don't know much about it, Or maybe, in that case, we can specialize the template, Or based on the fact whether its sparse matrix or not, we can select `value_type`, and work accordingly. – Nawaz Aug 16 '11 at 15:19
  • @Nawaz It may, in certain cases, be possible to implement bounds checking: rather than returning an `ElementProxy`, the `RowProxy` immediately calls `myOwner->get(...)`. If this function returns a reference, and the `operator[]` also returns a reference, there should be no problem. In a lot of cases, however, the elements aren't necessarily present in memory, and you need the `ElementProxy`. – James Kanze Aug 16 '11 at 15:30
1

There are two operators. To do what you want you must overload operator[] which returns vector of objects.

Art Spasky
  • 1,635
  • 2
  • 17
  • 30
0

The subscript operator in c++ is []. when you use a syntax like this "object[][]" you are calling the operator [] to scubscript the first object and then the second operator [] over the object selected by the first.

Substancially you can't overload the operator "[][]" because this operator does not exist. You should overload the subscript operator on the container object and then overload it also in the inner object.

Sebastiano Merlino
  • 1,273
  • 12
  • 23