overload []

D

Denis Remezov

Mario said:
.
Hi,

It's possible to overload the [] operator, but I wonder if it's possible to
somehow overload [][] and so forth.

My goal would be to switch from static array declaration into something
totaly dynamic with minimal change in the code.

The following code

int foo[NB_ROW][NB_COL];

foo[12][3] = 0;

would become:

Array2DimInt foo(NB_ROW, NB_COL);

foo[12][3] = 0;

A vector<vector<int> > that Dan suggested would work, but it is a bit too
generic for matrices (each row stores its own dimension, which you need
to care about). In some cases its suboptimal memory usage can be a factor
as well. Here are two more choices:

a) (Sean beat me to it, but I'm going to post this anyway since I've
typed it already).
Make the first [] return a proxy object. Here is an example idea
(it didn't feel right not making it a template):

template <typename T>
class Array2Dim {
vector<T> data_;
int width_;
public:
class RowProxy {
friend class Array2Dim;
vector<T>& data_;
int ofs_;
RowProxy(vector<T>& data, int ofs) : data_(data), ofs_(ofs) {}
public:
T& operator [](int col) {
return data_[ofs_+col];
}
};

RowProxy operator [](int row) {
return RowProxy(data_, row*width_);
}
//...
};

b) Consider using the (i, j) notation instead of [j]. I prefer the
[j] syntax, but (i, j) is superior in its implementation.
(Use operator() (int row, int col)).
Though as you mentioned you wanted to minimise the change to the existing
code, this may not work well for you.

Denis
 
M

Mario Charest

..
Hi,

It's possible to overload the [] operator, but I wonder if it's possible to
somehow overload [][] and so forth.

My goal would be to switch from static array declaration into something
totaly dynamic with minimal change in the code.

The following code

int foo[NB_ROW][NB_COL];

foo[12][3] = 0;

would become:

Array2DimInt foo(NB_ROW, NB_COL);

foo[12][3] = 0;

Am I making sense?

- Mario
 
D

Denis Remezov

John said:
Mario Charest said:
.
Hi,

It's possible to overload the [] operator, but I wonder if it's possible to
somehow overload [][] and so forth.

My goal would be to switch from static array declaration into something
totaly dynamic with minimal change in the code.

The following code

int foo[NB_ROW][NB_COL];

foo[12][3] = 0;

would become:

Array2DimInt foo(NB_ROW, NB_COL);

foo[12][3] = 0;

Am I making sense?

- Mario

The proxy class idea that others have suggested is a good general purpose
solution.

However in your particular case there is a simpler answer. Just have your
operator[] return a pointer the start of a row. So in an expression like

foo[12][3]

the first operator[] is your operator[] for the class, and the second
operator[] is just the regular operator[] that works on the pointer returned
by the first operator[].

john

Thanks! I completely missed it. The part I like the most is that you still can
use a vector as one contiguous storage.

Denis
 
D

Dan Cernat

Mario Charest said:
.
Hi,

It's possible to overload the [] operator, but I wonder if it's possible to
somehow overload [][] and so forth.

My goal would be to switch from static array declaration into something
totaly dynamic with minimal change in the code.

The following code

int foo[NB_ROW][NB_COL];

foo[12][3] = 0;

would become:

Array2DimInt foo(NB_ROW, NB_COL);

foo[12][3] = 0;

Am I making sense?

- Mario

try

using namespace std;

vector < vector < int> > foo;

it is totally dynamic. after you have data in, you can use it like:

foo[12][3] = 42;

however, the indexes shouldn't be out of range
 
W

Woebegone

Mario Charest said:
.
Hi,

It's possible to overload the [] operator, but I wonder if it's possible to
somehow overload [][] and so forth.

My goal would be to switch from static array declaration into something
totaly dynamic with minimal change in the code.

The following code

int foo[NB_ROW][NB_COL];

foo[12][3] = 0;

would become:

Array2DimInt foo(NB_ROW, NB_COL);

foo[12][3] = 0;

Am I making sense?

- Mario
Hi Mario,

It's not possible to directly overload [][]. However, you can overload [] to
return a type for which [] is also meaningful, thus synthesizing [][] for
the enclosing class. That's what Dan's sol'n does for you, using the
standard lib so you don't have to do the work.

Sean.
 
J

John Harrison

Mario Charest said:
.
Hi,

It's possible to overload the [] operator, but I wonder if it's possible to
somehow overload [][] and so forth.

My goal would be to switch from static array declaration into something
totaly dynamic with minimal change in the code.

The following code

int foo[NB_ROW][NB_COL];

foo[12][3] = 0;

would become:

Array2DimInt foo(NB_ROW, NB_COL);

foo[12][3] = 0;

Am I making sense?

- Mario

The proxy class idea that others have suggested is a good general purpose
solution.

However in your particular case there is a simpler answer. Just have your
operator[] return a pointer the start of a row. So in an expression like

foo[12][3]

the first operator[] is your operator[] for the class, and the second
operator[] is just the regular operator[] that works on the pointer returned
by the first operator[].

john
 
M

Mario Charest

John Harrison said:
Mario Charest said:
.
Hi,

It's possible to overload the [] operator, but I wonder if it's possible to
somehow overload [][] and so forth.

My goal would be to switch from static array declaration into something
totaly dynamic with minimal change in the code.

The following code

int foo[NB_ROW][NB_COL];

foo[12][3] = 0;

would become:

Array2DimInt foo(NB_ROW, NB_COL);

foo[12][3] = 0;

Am I making sense?

- Mario

The proxy class idea that others have suggested is a good general purpose
solution.

However in your particular case there is a simpler answer. Just have your
operator[] return a pointer the start of a row. So in an expression like

foo[12][3]

the first operator[] is your operator[] for the class, and the second
operator[] is just the regular operator[] that works on the pointer returned
by the first operator[].

I like the simplicity of the solution but it would not work in my case.

The arrays are used to map an image coming from a camera. Depending on
various factor the camera could be rotate 90 180 or 270 degrees. The
software current has different code path to handle the different angle, it's
a pain to maintain. I would like foo[12][3] to return the same pixel value
what ever the image angle (rotating the image beforehand is out of the
question for performance reason).

In that case using vector is out of the question. I think what I'll end up
doing is an image class with a Pixel( int x, int y ) member and I'll have a
class per angle. This means lots of change in the software but it doesn't
look like I have a choice.

Seems to me like only being able to overload [] is an oversight. If you can
overload one [] you should be able to overload [][], oh well.

Thanks everyone.
 
M

Mario Charest

Woebegone said:
Mario Charest said:
.
Hi,

It's possible to overload the [] operator, but I wonder if it's possible to
somehow overload [][] and so forth.

My goal would be to switch from static array declaration into something
totaly dynamic with minimal change in the code.

The following code

int foo[NB_ROW][NB_COL];

foo[12][3] = 0;

would become:

Array2DimInt foo(NB_ROW, NB_COL);

foo[12][3] = 0;

Am I making sense?

- Mario
Hi Mario,

It's not possible to directly overload [][]. However, you can overload [] to
return a type for which [] is also meaningful, thus synthesizing [][] for
the enclosing class. That's what Dan's sol'n does for you, using the
standard lib so you don't have to do the work.

I'll try it out thanks.
 
J

Jorge Rivera

Seems to me like only being able to overload [] is an oversight. If you can
overload one [] you should be able to overload [][], oh well.

Thanks everyone.

I disagree with this. Can't you use arbitrarily nesting of [][][] in C++?

Then your suggestion implies that in order for a custom class to use
this syntax, you are required to have an overload per level.
n-dimension array requiring n overloaded operators?

Doesn't sound all that good.

I your deciion of using operator() instead of operator[] is the way to go.

Good luck.

Jorge L.
Jorge L.
 
J

John Harrison

Jorge Rivera said:
Seems to me like only being able to overload [] is an oversight. If you can
overload one [] you should be able to overload [][], oh well.

Thanks everyone.

I disagree with this. Can't you use arbitrarily nesting of [][][] in C++?

Then your suggestion implies that in order for a custom class to use
this syntax, you are required to have an overload per level.
n-dimension array requiring n overloaded operators?

Doesn't sound all that good.

I your deciion of using operator() instead of operator[] is the way to go.

Good luck.

Jorge L.
Jorge L.

You can also do it with clever use of templates. This avoids the need to
write one class for each dimension of your n-dimensional array. Instead you
have a template with a integer parameter representing the array dimension.

Look at the boost MultiArray class for an example,
http://www.boost.org/libs/multi_array/doc/index.html

john
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top