Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Operator[ ] with two arguments

Status
Not open for further replies.

globos

Programmer
Nov 8, 2000
260
FR
Hello there,

I have defined a generic class for two-dimensional arrays, called Grid<G>.
I would like to define the operator[] with two arguments, ie the row and the column that define the coordinates of the item to access :

Code:
template<class G>
class Grid : public Array<G>
{
  // All other features skipped...
public:
  virtual const G& operator[] (int row, int column) const
  { // Body here.
  }
};

With VC++ 6.0 the compiler complains :
error C2804: binary 'operator [' has too many parameters

How would you work around this?
Or maybe another syntactic sugar.

Thanks.



--
Globos
 
You can't overload any operator with more arguments than it's normally allowed (e.g., you can't give binary [tt]+[/tt] three arguments). So you can't overload the [tt][][/tt] operator with more than one argument.
The best bet would be to have a class (say, [tt]GridRow[/tt] which represents a single row of the [tt]Grid[/tt] and then have [tt]Grid::eek:perator[][/tt] return a reference to an instance of this; there would also be a [tt]GridRow::eek:perator[][/tt] which would return a single element from the row, so you could write:
Code:
   Grid<SomeClass> x = ...;
   SomeClass item = x[1][3];
But that's about all you can do. If you want to do it all in one just define a [tt]Grid::getItem(int row, int col)[/tt] method.

[tt]_______________________________________
Roger [pc2]
The Eileens are out there[/tt]
 
If you REALLY think you need multiple arguments in one set of brackets, you could use the operator() instead of operator[]. Ex.
Code:
template <class T>
class CTest
{
public:
	CTest()
	{
		for ( int x = 0; x < 3; ++x )
		{
			for ( int y = 0; y < 3; ++y )
			{
				m_Data[ x ][ y ] = ((x + 1) * 10) + y + 1;
			}
		}
	}

	T operator()( int x, int y )
	{
		return m_Data[ x ][ y ];
	}

private:
	T m_Data[3][3];
};
It might look a bit confusing when you use it though.
 
If you come from a Fortran/Pascal background, something like
Code:
m_data[x,y] = 0;
may look legal to you. What it is actually doing is
Code:
x;
m_data[y] = 0;
because the comma is a statement separator as in
Code:
for (x = 0, y = 0; x < 100; ++x)
   ...
Having x by itself is perfectly legal since C/C++ are expression languages.
 
Warning: comma is NOT a statement separator, it's comma (binary) operator in this context: do the 1st expression (and all side effects are performed) then do the 2nd and yield the result (of the 2nd). It groups left-to-right.
No statement separators in C and C++ syntax (for example, a semicolon is a statement terminator;).
Apropos, for statement syntax is:
Code:
for (<expression>; <expression>; <expression>)
    statement
 
woja:
This may seem the solution in the sort term. I can't apply it for the moment because the internal representation of Grid<G> is a one-dimensional array, I can't afford to create rows just for the sake of a nice operator.

cpjust:
operator() is a good solution too, and I can apply it. But I won't do it because it is not coherent to the syntax with which my table structures are accessed(ie using operator[]).

What I thought also of is to use pairs of integers :
Code:
typedef pair<int, int> Coordinates;
template<class G>
class Grid : public Array<G>
{
  // All other features skipped...
public:
  virtual const G& operator[] (const Coordinates& coords) const
  { // Body here.
  }
};


int main ()
{
  Grid<double> grid_reals (100, 100);//make a 100x100 grid.
  grid_reals[make_pair (1, 1)] = 3.14159;
  return 0;
}

But efficiency would be to affected, and the syntax bonus is difficult to see.

Finally I gonna stay with a simple item(int, int) function.

Anyway, thanks you guys for your thoughts.

--
Globos
 
About the comma:
It's a binary operator when used like this:
Code:
double y = 0;
double z = 0;
double x = (y = sin(2.13), z = cos(y), sqrt(z));
which sets does:
[ol 1]
[li][tt]y = sin(2.13)[/tt][/li]
[li][tt]z = cos(y)[/tt][/li]
[li][tt]sqrt(z)[/tt][/li]
[/ol]
and the value is [tt]sqrt(z)[/tt]. Everything being evaluated left to right.
But in:
Code:
double x = myfunc(f1(a), f2(b), f3(c));
the arguments are not necessarily evaluated left-to-right (this depends on the implementation).
What I am trying to say is that the comma-operator is different from the argument-separator.
Personally, in over 20 years of programming in C I've only used the comma-operator once and that was only so I could say that I'd used it.

[tt]_______________________________________
Roger [pc2]
The Eileens are out there[/tt]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top