Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Can we override [][] ?

Reply
Thread Tools

Can we override [][] ?

 
 
Jim Langston
Guest
Posts: n/a
 
      05-31-2006
I wanted to do an operator override for [][] but couldnt' figure out the
syntax. I tried this (code that doesn't compile commented out with //:

class CMyBitmap
{
public:
CMyBitmap( int Rows, int Columns ): Rows_( Rows ), Columns_( Columns )
{
Data_ = new SPixel[ Rows * Columns ];
}
~CMyBitmap()
{
delete[] Data_;
}

// error C2804: binary 'operator [' has too many parameters
// SPixel& operator[]( const int Row, const int Column )
// {
// return Data_[ Columns_ * Row + Column ];
// }

// error C2092: '[]' array element type cannot be function
// SPixel& operator[][]( const int Row, const int Column )

SPixel& Pixel( const int Row, const int Column )
{
return Data_[ Columns_ * Row + Column ];
}

private:
SPixel* Data_;
int Rows_;
int Columns_;

// No copy or assignment yet so disable by making private.
CMyBitmap ( CMyBitmap const& ) {};
CMyBitmap& operator=( CMyBitmap const& ) {};

};

Can we override 2d array access?


 
Reply With Quote
 
 
 
 
Mike Wahler
Guest
Posts: n/a
 
      05-31-2006

"Jim Langston" <(E-Mail Removed)> wrote in message
news:KB5fg.137$(E-Mail Removed)...
>I wanted to do an operator override for [][] but couldnt' figure out the
>syntax. I tried this (code that doesn't compile commented out with //:
>
> class CMyBitmap
> {
> public:
> CMyBitmap( int Rows, int Columns ): Rows_( Rows ), Columns_( Columns )
> {
> Data_ = new SPixel[ Rows * Columns ];
> }
> ~CMyBitmap()
> {
> delete[] Data_;
> }
>
> // error C2804: binary 'operator [' has too many parameters
> // SPixel& operator[]( const int Row, const int Column )
> // {
> // return Data_[ Columns_ * Row + Column ];
> // }
>
> // error C2092: '[]' array element type cannot be function
> // SPixel& operator[][]( const int Row, const int Column )
>
> SPixel& Pixel( const int Row, const int Column )
> {
> return Data_[ Columns_ * Row + Column ];
> }
>
> private:
> SPixel* Data_;
> int Rows_;
> int Columns_;
>
> // No copy or assignment yet so disable by making private.
> CMyBitmap ( CMyBitmap const& ) {};
> CMyBitmap& operator=( CMyBitmap const& ) {};
>
> };
>
> Can we override 2d array access?


Certainly. But...
[][] is not an operator, it's two instances of the single
operator []. If you have your operator[] do the 'right
thing', you shouldn't have any problems using expressions
such as x[], x[][], x[][][], etc. Post back if you need
more help or an example.

-Mike



 
Reply With Quote
 
 
 
 
Jim Langston
Guest
Posts: n/a
 
      05-31-2006

"Mike Wahler" <(E-Mail Removed)> wrote in message
news:5I5fg.9653$(E-Mail Removed) nk.net...
>
> "Jim Langston" <(E-Mail Removed)> wrote in message
> news:KB5fg.137$(E-Mail Removed)...
>>I wanted to do an operator override for [][] but couldnt' figure out the
>>syntax. I tried this (code that doesn't compile commented out with //:
>>
>> class CMyBitmap
>> {
>> public:
>> CMyBitmap( int Rows, int Columns ): Rows_( Rows ), Columns_( Columns )
>> {
>> Data_ = new SPixel[ Rows * Columns ];
>> }
>> ~CMyBitmap()
>> {
>> delete[] Data_;
>> }
>>
>> // error C2804: binary 'operator [' has too many parameters
>> // SPixel& operator[]( const int Row, const int Column )
>> // {
>> // return Data_[ Columns_ * Row + Column ];
>> // }
>>
>> // error C2092: '[]' array element type cannot be function
>> // SPixel& operator[][]( const int Row, const int Column )
>>
>> SPixel& Pixel( const int Row, const int Column )
>> {
>> return Data_[ Columns_ * Row + Column ];
>> }
>>
>> private:
>> SPixel* Data_;
>> int Rows_;
>> int Columns_;
>>
>> // No copy or assignment yet so disable by making private.
>> CMyBitmap ( CMyBitmap const& ) {};
>> CMyBitmap& operator=( CMyBitmap const& ) {};
>>
>> };
>>
>> Can we override 2d array access?

>
> Certainly. But...
> [][] is not an operator, it's two instances of the single
> operator []. If you have your operator[] do the 'right
> thing', you shouldn't have any problems using expressions
> such as x[], x[][], x[][][], etc. Post back if you need
> more help or an example.


I had goggled for operator[] but goggle doesn't seem to index special
characters (such as '[') so the hits weren't very orderly and it took me a
long time to even find the syntax for [] My manual didn't give me any
examples, time to get a new manual.

I would need an example please, as I don't know how to override[] to accept
two paramters but you seem to indicate it is two instances of []. What is
the 'right thing' or can you direct me to a web page on the subject? As I
said, in this case Google was not my friend.


 
Reply With Quote
 
Tomás
Guest
Posts: n/a
 
      05-31-2006
Jim Langston posted:


> I would need an example please, as I don't know how to override[] to
> accept two paramters but you seem to indicate it is two instances of
> []. What is the 'right thing' or can you direct me to a web page on
> the subject? As I said, in this case Google was not my friend.



I only spent fifteen minutes on this, so it's by no means perfect.

Untested code:


class ChessBoard {
public:

class Square {
public:
enum SquareContents {
empty, pawn, castle, horse, bishop, queen, king } contents;

Square &operator=( SquareContents const sc )
{
contents = sc;
return *this;
}
};


Square squares[64];


class HorizontalCoordinate {
private:

ChessBoard &cb;
unsigned const x;

public:

HorizontalCoordinate(ChessBoard &arg_cb, unsigned const arg_x)
: cb(arg_cb), x(arg_x) {}

Square &operator[]( unsigned const y )
{
return cb.squares[ x * 8 + y ];
}
};


HorizontalCoordinate operator[](unsigned const x)
{
return HorizontalCoordinate(*this, x);
}

};

int main()
{
ChessBoard board;

board[3][5] = ChessBoard::Square::bishop;
}


As you can see, a simple member function (or even function-style
operator) would probably be better.

-Tomás
 
Reply With Quote
 
Cy Edmunds
Guest
Posts: n/a
 
      05-31-2006

"Jim Langston" <(E-Mail Removed)> wrote in message
news:KB5fg.137$(E-Mail Removed)...
>I wanted to do an operator override for [][] but couldnt' figure out the
>syntax. I tried this (code that doesn't compile commented out with //:
>
> class CMyBitmap
> {
> public:
> CMyBitmap( int Rows, int Columns ): Rows_( Rows ), Columns_( Columns )
> {
> Data_ = new SPixel[ Rows * Columns ];
> }
> ~CMyBitmap()
> {
> delete[] Data_;
> }
>
> // error C2804: binary 'operator [' has too many parameters
> // SPixel& operator[]( const int Row, const int Column )
> // {
> // return Data_[ Columns_ * Row + Column ];
> // }
>
> // error C2092: '[]' array element type cannot be function
> // SPixel& operator[][]( const int Row, const int Column )
>
> SPixel& Pixel( const int Row, const int Column )
> {
> return Data_[ Columns_ * Row + Column ];
> }
>
> private:
> SPixel* Data_;
> int Rows_;
> int Columns_;
>
> // No copy or assignment yet so disable by making private.
> CMyBitmap ( CMyBitmap const& ) {};
> CMyBitmap& operator=( CMyBitmap const& ) {};
>
> };
>
> Can we override 2d array access?
>


You should declare your operator as

something operator [] (int Row);

Then "something" must define

SPixel &operator [] (int Column);

The question is, what is "something"? The best thing is probably to make it
a separate class. However, a well known cheat is to make "something" an
SPixel*, which automatically provides this second operator by the usual
rules for subscripting a pointer. Hence

SPixel *operator [] (int Row) {return Row * Columns_;}

will do it!

Cy


 
Reply With Quote
 
Noah Roberts
Guest
Posts: n/a
 
      05-31-2006

Jim Langston wrote:
> I wanted to do an operator override for [][] but couldnt' figure out the
> syntax.


http://www.parashift.com/c++-faq-lit...html#faq-13.10

 
Reply With Quote
 
Tomás
Guest
Posts: n/a
 
      05-31-2006
Tomás posted:


> I only spent fifteen minutes on this, so it's by no means perfect.



Taking Cy's trick on-board, you could change it to:


class ChessBoard {
public:

class Square {
public:
enum SquareContents {
empty, pawn, castle, horse, bishop, queen, king } contents;

Square &operator=( SquareContents const sc )
{
contents = sc;
return *this;
}
};

Square squares[64];


Square *operator[](unsigned const x)
{
return squares + 8 * (x-1);
}

};

int main()
{
ChessBoard board;

board[3][5] = ChessBoard::Square::bishop;
}


-Tomás
 
Reply With Quote
 
Jim Langston
Guest
Posts: n/a
 
      05-31-2006

"Tomás" <No.Email@Address> wrote in message
news:Tl6fg.9753$(E-Mail Removed)...
> Jim Langston posted:
>
>
>> I would need an example please, as I don't know how to override[] to
>> accept two paramters but you seem to indicate it is two instances of
>> []. What is the 'right thing' or can you direct me to a web page on
>> the subject? As I said, in this case Google was not my friend.

>
>
> I only spent fifteen minutes on this, so it's by no means perfect.
>
> Untested code:
>
>
> class ChessBoard {
> public:
>
> class Square {
> public:
> enum SquareContents {
> empty, pawn, castle, horse, bishop, queen, king } contents;
>
> Square &operator=( SquareContents const sc )
> {
> contents = sc;
> return *this;
> }
> };
>
>
> Square squares[64];
>
>
> class HorizontalCoordinate {
> private:
>
> ChessBoard &cb;
> unsigned const x;
>
> public:
>
> HorizontalCoordinate(ChessBoard &arg_cb, unsigned const arg_x)
> : cb(arg_cb), x(arg_x) {}
>
> Square &operator[]( unsigned const y )
> {
> return cb.squares[ x * 8 + y ];
> }
> };
>
>
> HorizontalCoordinate operator[](unsigned const x)
> {
> return HorizontalCoordinate(*this, x);
> }
>
> };
>
> int main()
> {
> ChessBoard board;
>
> board[3][5] = ChessBoard::Square::bishop;
> }
>
>
> As you can see, a simple member function (or even function-style
> operator) would probably be better.


Thank you. Works well. This is my solution if anyone is interested.

union SPixel
{
struct {
unsigned char B, G, R, A;
};
unsigned long Value;
};

class CMyBitmap
{
public:
CMyBitmap( int Rows, int Columns ): Rows_( Rows ), Columns_( Columns )
{
Data_ = new SPixel[ Rows * Columns ];
}
~CMyBitmap()
{
delete[] Data_;
}
SPixel& Pixel( const int Row, const int Column )
{
if ( Row > Rows_ || Row < 0 )
throw std::string( "Out of bounds for row" );
else if ( Column > Columns_ || Column < 0 )
throw std::string( "Out of bounds for column" );
else
return Data_[ Columns_ * Row + Column ];
}

class HorizCoord
{
public:
HorizCoord( CMyBitmap& Bitmap, const int Row ): Bitmap_( Bitmap ),
Row_( Row ) {}
SPixel& operator[]( const int Column )
{
if ( Column > Bitmap_.Columns_ || Column < 0 )
throw std::string( "Out of bounds for column" );
else
return Bitmap_.Data_[ Bitmap_.Columns_ * Row_ + Column ];
}
private:
CMyBitmap& Bitmap_;
const Row_;
};

HorizCoord operator[] (int const Row)
{
if ( Row > Rows_ || Row < 0 )
throw std::string( "Out of bounds for row" );
else
return HorizCoord(*this, Row);
}

private:
SPixel* Data_;
int Rows_;
int Columns_;

// No copy or assignment yet so disable by making private.
CMyBitmap ( CMyBitmap const& ) {};
CMyBitmap& operator=( CMyBitmap const& ) {};

};

int main()
{
SPixel Pixel;
Pixel.Value = 0x01020304;
std::cout << "0x01020304 by color: " << (int) Pixel.A << " " << (int)
Pixel.R << " " << (int) Pixel.G << " " << (int) Pixel.B << std::endl;

CMyBitmap BitMap( 100, 100 );

BitMap.Pixel(10, 10).R = 255;
BitMap.Pixel(10, 10).B = 255;
BitMap.Pixel(10, 10).G = 255;
BitMap.Pixel(10, 10).A = 255;
std::cout << "All bits set by value: " <<BitMap.Pixel(10, 10).Value <<
std::endl;

BitMap[15][15].R = 128;
BitMap[15][15].B = 129;
BitMap[15][15].G = 130;
BitMap[15][15].A = 131;
std::cout << "Set using [][]: " << BitMap.Pixel(15, 15).Value <<
std::endl;

BitMap.Pixel(20, 20).Value = 0xFFFF0000;
std::cout << "0xFFFF0000 by color: " << (int) BitMap.Pixel(20, 20).A <<
" " << (int) BitMap.Pixel(20, 20).R << " " << (int) BitMap.Pixel(20, 20).G
<< " " << (int) BitMap.Pixel(20, 20).B << std::endl;

// Lets just prove that Intel is Bigendian.
unsigned char* pchar = reinterpret_cast<unsigned char*>(
&(BitMap.Pixel( 20, 20 ).Value ) );
std::cout << "First Byte:" << (int) *(pchar++) << std::endl;
std::cout << "Second Byte:" << (int) *(pchar++) << std::endl;
std::cout << "Third Byte:" << (int) *(pchar++) << std::endl;
std::cout << "Fourth Byte:" << (int) *pchar << std::endl;

std::string wait;
std::cin >> wait;
}


 
Reply With Quote
 
Jim Langston
Guest
Posts: n/a
 
      05-31-2006

"Cy Edmunds" <(E-Mail Removed)> wrote in message
news:Wv6fg.9779$(E-Mail Removed)...
>
> "Jim Langston" <(E-Mail Removed)> wrote in message
> news:KB5fg.137$(E-Mail Removed)...
>>I wanted to do an operator override for [][] but couldnt' figure out the
>>syntax. I tried this (code that doesn't compile commented out with //:
>>
>> class CMyBitmap
>> {
>> public:
>> CMyBitmap( int Rows, int Columns ): Rows_( Rows ), Columns_( Columns )
>> {
>> Data_ = new SPixel[ Rows * Columns ];
>> }
>> ~CMyBitmap()
>> {
>> delete[] Data_;
>> }
>>
>> // error C2804: binary 'operator [' has too many parameters
>> // SPixel& operator[]( const int Row, const int Column )
>> // {
>> // return Data_[ Columns_ * Row + Column ];
>> // }
>>
>> // error C2092: '[]' array element type cannot be function
>> // SPixel& operator[][]( const int Row, const int Column )
>>
>> SPixel& Pixel( const int Row, const int Column )
>> {
>> return Data_[ Columns_ * Row + Column ];
>> }
>>
>> private:
>> SPixel* Data_;
>> int Rows_;
>> int Columns_;
>>
>> // No copy or assignment yet so disable by making private.
>> CMyBitmap ( CMyBitmap const& ) {};
>> CMyBitmap& operator=( CMyBitmap const& ) {};
>>
>> };
>>
>> Can we override 2d array access?
>>

>
> You should declare your operator as
>
> something operator [] (int Row);
>
> Then "something" must define
>
> SPixel &operator [] (int Column);
>
> The question is, what is "something"? The best thing is probably to make
> it a separate class. However, a well known cheat is to make "something" an
> SPixel*, which automatically provides this second operator by the usual
> rules for subscripting a pointer. Hence
>
> SPixel *operator [] (int Row) {return Row * Columns_;}
>
> will do it!


This is an excellant solution, but I can't check for column overflow. I
think I'll keep the existing solution I have right now, but keep your's in
mind for other classes.

Thanks!


 
Reply With Quote
 
Axter
Guest
Posts: n/a
 
      05-31-2006

Noah Roberts wrote:
> Jim Langston wrote:
> > I wanted to do an operator override for [][] but couldnt' figure out the
> > syntax.

>
> http://www.parashift.com/c++-faq-lit...html#faq-13.10


I recommend NOT following this particular FAQ.
It uses contrive logic to support promoting the use of non-standard
syntax to reference a matrix.

I recommend using standard syntax [][] over more ambiguous ()() method.
I also recommmend using vector<vector<T> > type.

See following links for example implementations:
http://code.axter.com/dynamic_2d_array.h
http://www.codeguru.com/forum/showthread.php?t=231046
http://www.codeguru.com/forum/showth...hreadid=297838

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can't override CSS class!!! Jibba Jabba HTML 11 09-29-2007 11:14 PM
Can you override the "<big>" tag with CSS? Nocturnal HTML 3 07-06-2006 11:08 PM
Any DVD Player that can override User Prohibitions? Walter Traprock DVD Video 3 12-03-2005 11:43 PM
Using inheritance for web pages - why have a Page_Init when you can override OnInit? ASP .Net 2 07-16-2003 07:32 PM
Using inheritance for web pages - why have a Page_Init when you can override OnInit? ASP .Net 2 07-13-2003 04:07 AM



Advertisments