Topic: operator[](int,int)
Author: s5vijen@portland.watson.ibm.com (Anil Vijendran)
Date: 1995/08/02 Raw View
>>>>> On 28 Jul 1995 18:22:14 +0200, kanze@gabi-soft.fr (J. Kanze)
said:
kanze> Anil Vijendran (s5vijen@portland.watson.ibm.com) wrote:
kanze> |> >>>>> On Mon, 24 Jul 1995 16:12:58 GMT, fjh@munta.cs.mu.OZ.AU (Fergus
kanze> |> Henderson) said:
kanze> |> [deleted]
[deleted]
kanze> |> In a sense it does break some code... the users of the class that
kanze> |> defines the non-standard operator[](int, int) and the standard
kanze> |> operator[](int, int).
^^^^^^^^^^^^^^^^^^^
Sorry that was my typo. I meant to say "the standard
operator[](int)".
kanze> Except that such code cannot legally exist, since there is no standard
kanze> operator[]( int , int ).
--
Peace.... +<:-)
Anil
akv@cacs.usl.edu
s5vijen@watson.ibm.com
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/08/02 Raw View
matt@godzilla.EECS.Berkeley.EDU (Matt Austern) writes:
>fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>
>> But no standard-conforming code defines `operator[] (int, int)'.
>> If Borland makes `a[ x, y ]' call `operator[] (int, int)' in
>> the case that `a' has an `operator[] (int, int)', it won't
>> affect any standard-conforming code.
>
>I don't think that's true. a[x, y] is a legal C++ expression: it
>is equivalent to a[(x, y)], and, if evaluating x has no side
>effects, it is equivalent to a[y].
You missed the point. `a[x, y]' is a legal C++ expression, but
`operator[] (int, int)' is not a legal C++ declaration. If Borland
were to change the meaning of `a[x, y]' only if the code declares
an `operator[]' with two arguments, then that cannot affect any
standard-conforming code, since no standard-conforming code can
possibly contain such a declaration.
// prog1.cpp - strictly conforming C++ code
struct Foo {
int operator [] (int);
}
void bar(int x, int y) {
Foo foo;
foo[x,y]; // In any standard-conforming compiler, this
// must be equivalent to `foo[y]'.
}
// prog2.cpp - this code is not strictly conforming C++
struct Foo {
int operator [] (int, int);
// The above declaration is "ill-formed".
// The compiler must issue a diagnostic.
}
void bar(int x, int y) {
Foo foo;
foo[x,y]; // Once the above diagnostic has been issued,
// the compiler is free to do anything it likes
// with this code, including calling
// `Foo::operator[](int, int)'.
}
--
Fergus Henderson | Designing grand concepts is fun;
fjh@cs.mu.oz.au | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC 8B 3E 0F 01 E7 5D C4 3F
Author: pardoej@lonnds.ml.com (Julian Pardoe LADS LDN X1428)
Date: 1995/07/28 Raw View
In article <9520602.10243@mulga.cs.mu.OZ.AU>, fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
-->But no standard-conforming code defines `operator[] (int, int)'.
-->If Borland makes `a[ x, y ]' call `operator[] (int, int)' in
-->the case that `a' has an `operator[] (int, int)', it won't
-->affect any standard-conforming code.
-->Borland would just need to be careful that `a [x, y]' behaves the same
-->way as in standard C++ if `a' does not have a multi-argument
-->operator[] function.
The problem isn't that standard-conforming code can already define
operator[] (int, int) but that in standard-conforming code a[x, y]
already has a meaning: it's equivalent to a[(x, y)]. There's no con-
ceptual problem in having this expression invoke operator[] (int, int).
After all function calls work this way; f (x, y) is not the same as
f ((x, y)). However the change would silently alter the meaning of
standard-conforming code and that's something we wish to avoid.
-- jP --
Author: xmsb@shadow.borland.com (Maurice S. Barnum)
Date: 1995/07/28 Raw View
Uwe Tantz <c4037@rphc1.physik.uni-regensburg.de> writes:
>When I originally posted this question, I did not think about conflicts
>with comma operator. (personally I use the comma operator very seldom. I
>think I could "live" very well without it.)
>Now, knowing about this, I agree that BC 3.1's behaviour may lead into
>trouble. But I am very sure that BC 3.1 handles the operator[] as I wrote.
it doesn't in my version:
-=-=-=-=-=-=-=-
[c:\tmp]type foo.cpp
struct foo {
int operator[](int, int) { return 8; }
} f;
[c:\tmp]s:\product\bc\BC310AF.CD\BORLANDC\bin\bcc -A foo.cpp
Borland C++ Version 3.1 Copyright (c) 1992 Borland International
foo.cpp:
Error foo.cpp 2: 'foo::operator [](int,int)' must be declared with one parameter
*** 1 errors in Compile ***
Available memory 4231484
[c:\tmp]
-=-=-=-=-=-=-=-
as far having an operator to access multi-dimensional arrays, two
suggestions:
1) use operator()(int, int);
2) take a look at a recent copy of C++ Report (I think this
month's, but i'm not sure), for one technique that uses []'s.
--xmsb
xmsb@borland.com
xmsb@slaughter.com
Author: Uwe Tantz <c4037@rphc1.physik.uni-regensburg.de>
Date: 1995/07/28 Raw View
When I originally posted this question, I did not think about conflicts
with comma operator. (personally I use the comma operator very seldom. I
think I could "live" very well without it.)
Now, knowing about this, I agree that BC 3.1's behaviour may lead into
trouble. But I am very sure that BC 3.1 handles the operator[] as I wrote.
I do not know, if the compiler is able to compute brackets including a
comma as it has to (I don't think so). I will try it out and post the
result here.
Finally I have to say that BC 3.1 a very old compiler. I have no idea how
borland's latest compiler (4.5 or so) behaves. Although 3.1 is old, I
think it is rather good. It has some (not many) bugs, which are well
known. I know several people who would not want to change to one of the
newer (borland-)compilers.
Uwe
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/07/28 Raw View
Anil Vijendran (s5vijen@portland.watson.ibm.com) wrote:
|> >>>>> On Mon, 24 Jul 1995 16:12:58 GMT, fjh@munta.cs.mu.OZ.AU (Fergus
|> Henderson) said:
|> [deleted]
|> Fergus> But no standard-conforming code defines `operator[] (int, int)'.
|> Fergus> If Borland makes `a[ x, y ]' call `operator[] (int, int)' in
|> Fergus> the case that `a' has an `operator[] (int, int)', it won't
|> Fergus> affect any standard-conforming code.
|> But what if `a' has an operator[](int) too? In that case, code like
|> a[x, y] which would resolve to operator[](int) by the standard, should
|> be ambiguous. I assume Borland would spew an ambiguity diagnostic,
|> shouldn't it?
It's really up to Borland to decide what to do in this case. Once you
are using an extension, you cannot argue about what the standard says.
|> In a sense it does break some code... the users of the class that
|> defines the non-standard operator[](int, int) and the standard
|> operator[](int, int).
Except that such code cannot legally exist, since there is no standard
operator[]( int , int ).
--
James Kanze (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle--
--Beratung in industrieller Datenverarbeitung
Author: s5vijen@portland.watson.ibm.com (Anil Vijendran)
Date: 1995/07/25 Raw View
>>>>> On Mon, 24 Jul 1995 16:12:58 GMT, fjh@munta.cs.mu.OZ.AU (Fergus
Henderson) said:
[deleted]
Fergus> But no standard-conforming code defines `operator[] (int, int)'.
Fergus> If Borland makes `a[ x, y ]' call `operator[] (int, int)' in
Fergus> the case that `a' has an `operator[] (int, int)', it won't
Fergus> affect any standard-conforming code.
But what if `a' has an operator[](int) too? In that case, code like
a[x, y] which would resolve to operator[](int) by the standard, should
be ambiguous. I assume Borland would spew an ambiguity diagnostic,
shouldn't it?
In a sense it does break some code... the users of the class that
defines the non-standard operator[](int, int) and the standard
operator[](int, int).
--
Peace.... +<:-)
Anil
akv@cacs.usl.edu
s5vijen@watson.ibm.com
Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/07/25 Raw View
In article <MATT.95Jul24105500@godzilla.EECS.Berkeley.EDU>
matt@godzilla.EECS.Berkeley.EDU (Matt Austern) writes:
|> In article <9520602.10243@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
|> > But no standard-conforming code defines `operator[] (int, int)'.
|> > If Borland makes `a[ x, y ]' call `operator[] (int, int)' in
|> > the case that `a' has an `operator[] (int, int)', it won't
|> > affect any standard-conforming code.
|> I don't think that's true. a[x, y] is a legal C++ expression: it
|> is equivalent to a[(x, y)], and, if evaluating x has no side
|> effects, it is equivalent to a[y].
|> I can't imagine any circumstances in which a[x,y] is a useful
|> expression, but it is legal and it is broken by the addition
|> of operator[](int,int).
No, Fergus is right. Although I don't have Borland C++ to see how
they do it, it is possible to do it legally (as an extension). The
normal operator, must work correctly in all cases where the user has
not overloaded operator[] with two parameters. In the case where the
user has overloaded operator[] with two parameters, the users is using
an extension, and the implementation is free to do what it wants.
Personally, I don't like this kind of extension. I fear that it will
lead to too many questions as to what the language really is. But
this is a question that the market will decide; if Borland thinks that
such options will sell more compilers (and they know more about
compiler marketing than I do), then they are correct in implementing
it. (They are not alone: g++ is full of extensions. This is one of
the things I definitly do *not* like about g++.)
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/07/24 Raw View
kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
>Uwe Tantz <c4037@rphc1.physik.uni-regensburg.de> writes:
>
>|> When I wrote a matrix-type container using Borland C++ 3.1, I also added
>|> an
>|> operator[] (int x, int y)
>|> this allowed me to cache matrix elements easily at matrix-level. (I also
>|> found the syntax more convenient a[x,y] instead of a[x][y]).
>
>This sounds like a serious bug in Borland C++.
I have no idea of the accuracy of Uwe Tantz's comments, but even if
they are true, it doesn't necessarily indicate a bug in Borland C++.
It is certainly possible for a conforming C++ implementation to
allow multi-argument operator[] as an extension.
>In all compilers, the
>expression `a[ x , y ]' is (or should be) defined, and has a definite
>meaning (for user defined types): `a.operator[]( (x , y) )'. Note the
>additional parentheses: operator[] takes a single parameter. `x' is
>evaluated before y, and the results of this evaluation are discarded.
>(Presumably, the expression `x' will have some side effects.
>Otherwise, the expression is useless.)
Presumeably Borland C++ will still allow this use of the comma
operator if `a' does not define a multi-argument operator [].
>Allowing `operator[]( int , int )' to be defined is a permitted
>extension (I believe);
If invoked in the appropriate standard-conforming mode, the
implementation must issue a diagnostic. So if Borland C++
were to report
warning: ANSI/ISO C++ does not allow multi-dimensional operator[]
if invoked with the appropriate options (including -A),
and then implement it as an extension, that would be standard-conforming.
>calling it in the case of `a[ x , y ]' is illegal,
No, once the implementation has issued a diagnostic,
it's free to do as it pleases.
>and will no doubt break certain code.
But no standard-conforming code defines `operator[] (int, int)'.
If Borland makes `a[ x, y ]' call `operator[] (int, int)' in
the case that `a' has an `operator[] (int, int)', it won't
affect any standard-conforming code.
Borland would just need to be careful that `a [x, y]' behaves the same
way as in standard C++ if `a' does not have a multi-argument
operator[] function.
--
Fergus Henderson | Designing grand concepts is fun;
fjh@cs.mu.oz.au | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC 8B 3E 0F 01 E7 5D C4 3F
Author: matt@godzilla.EECS.Berkeley.EDU (Matt Austern)
Date: 1995/07/24 Raw View
In article <9520602.10243@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
> But no standard-conforming code defines `operator[] (int, int)'.
> If Borland makes `a[ x, y ]' call `operator[] (int, int)' in
> the case that `a' has an `operator[] (int, int)', it won't
> affect any standard-conforming code.
I don't think that's true. a[x, y] is a legal C++ expression: it
is equivalent to a[(x, y)], and, if evaluating x has no side
effects, it is equivalent to a[y].
I can't imagine any circumstances in which a[x,y] is a useful
expression, but it is legal and it is broken by the addition
of operator[](int,int).
--
Matt Austern He showed his lower teeth. "We
matt@physics.berkeley.edu all have flaws," he said, "and
http://dogbert.lbl.gov/~matt mine is being wicked."
Author: Etay Bogner <ebogner@ird.scitex.com>
Date: 1995/07/24 Raw View
Just as a case study, I overloaded "operator ,", so the call
A[i,j]
can be translated to
A.operator[](operator,(i,j))
where i,j are NOT ints !!!
I think it will be VERY bad to overload operator,(int,int) !!!
Anyway, here it is
/************/
#include <iostream.h>
#include <bool.h> // from STL
#include <function.h> // from STL
template <class T, long rows, long cols>
struct matrix {
class index;
class matrix_index { // this is a private type. will be created only in
operator,
friend class matrix;
friend class matrix::index;
long mIndex;
matrix_index(long index) : mIndex(index) {};
};
class index {
long mIndex;
public :
index(long index = 0) : mIndex(index) {};
long operator++() { return ++mIndex;};
long operator--() { return --mIndex;};
long operator++(int) { return mIndex++;};
long operator--(int) { return mIndex--;};
bool operator ==(long index2) const { return ( mIndex == index2 );};
bool operator <(long index2) const { return ( mIndex < index2 );};
// the rest of them will be created from the templates in <function.h>
operator long() const { return mIndex;}; // not mutable
index operator = (long index){ return ( mIndex = index );}; // not
mutable
matrix_index operator,(matrix::index index2) const {
return matrix_index(mIndex * index2); // currently, not a big deal
here...
}
};
T& operator [](matrix_index mat_index) { return ar[mat_index.mIndex]; };
private :
T ar[cols*rows];
};
typedef matrix<char, 8, 8> chess_board;
void main() {
chess_board board;
chess_board::index i;
chess_board::index j;
for ( i = 0; i < 8 ; ++i )
for ( j = 0; j < 8 ; ++j )
board[i,j] = 'A';
for ( i = 0; i < 8 ; ++i ) {
for ( j = 0; j < 8 ; ++j )
cout << board[i,j];
cout << endl;
}
}
/************/
I wrote this in 10 minutes, so I'm sure there are errors here ( at least
design errors, no compile errors, I checked and ran it ).
Anyway, I'm SURE that it's quite a bad idea to write such code...
OR
Is a sparse matrix a good example for this ? so one can calculate the pointer
to cells in the operator,.
Or a chess board where the class index is actually a char* based one, so code
like:
board["a1","d2"] is accepted ?
so one can actually play from/to cout/cin in a nice way ?
-- Etay Bogner,
-- ebogner@ird.scitex.com ( OLD ),
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.
Author: jason@cygnus.com (Jason Merrill)
Date: 1995/07/24 Raw View
>>>>> Matt Austern <matt@godzilla.EECS.Berkeley.EDU> writes:
> In article <9520602.10243@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>> But no standard-conforming code defines `operator[] (int, int)'.
>> If Borland makes `a[ x, y ]' call `operator[] (int, int)' in
>> the case that `a' has an `operator[] (int, int)', it won't
>> affect any standard-conforming code.
> I don't think that's true. a[x, y] is a legal C++ expression: it
> is equivalent to a[(x, y)], and, if evaluating x has no side
> effects, it is equivalent to a[y].
> I can't imagine any circumstances in which a[x,y] is a useful
> expression, but it is legal and it is broken by the addition
> of operator[](int,int).
Fergus' point, with which I agree, is that when you write ill-formed code,
all bets are off; the compiler can do whatever it wants with it. This can
include accepting and correctly (according to the compiler programmer)
executing it.
1.7 Processor compliance [intro.compliance]
1 Every conforming C++ processor shall, within its resource limits,
accept and correctly execute well-formed C++ programs, and shall issue
at least one diagnostic message when presented with any ill-formed
program that contains a violation of any diagnosable semantic rule or
of any syntax rule, except as noted herein.
This does not require the processor to accept and correctly execute
well-formed portions of programs, only full programs.
Jason
Author: richardcox@cix.compulink.co.uk ("Richard Cox")
Date: 1995/07/25 Raw View
> Message-ID: <MATT.95Jul24105500@godzilla.EECS.Berkeley.EDU>
> From: matt@physics.berkeley.edu
>
> In article <9520602.10243@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU
> > (Fergus Henderson) writes:
>
> > But no standard-conforming code defines `operator[] (int, int)'.
> > If Borland makes `a[ x, y ]' call `operator[] (int, int)' in
> > the case that `a' has an `operator[] (int, int)', it won't
> > affect any standard-conforming code.
>
> I don't think that's true. a[x, y] is a legal C++ expression: it
> is equivalent to a[(x, y)], and, if evaluating x has no side
> effects, it is equivalent to a[y].
>
> I can't imagine any circumstances in which a[x,y] is a useful
> expression, but it is legal and it is broken by the addition
> of operator[](int,int).
You missed the point.
If operator[](int, int) has not been defined and Borland implement this
extenstion "properly" (i.e. the afore mentioned operator is only
considered _if_ it has been defined standard conforming code will be
uneffected because it will not define that operator).
So by adding a definition of operator[](int, int) the code is made
non-conforming (a diagnotic is required) so its use in a conforming
compiler which does not provide this extension will not compile (or at
least not compile into anything useful).
However moveing code in the other direction (to the B compliler) will be
OK, no dual-arg [] so no call to it and a[x, y] will be treated as
a[(x,y)].
IMO the use of dual-arg [] would be confusing unless it was made very
clear that this was an extenstion; since a[x, y] seen in code should
trigger alarms to any (resonably competent) C++ programmer.
--------------------------------------------------------------
Richard Cox: Data Innovation Group, SMS United Kingdom Limited
#include <std-disclaimer.h>
richardcox@cix.compulink.co.uk
Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/07/18 Raw View
In article <Pine.SOL.3.90.950706113001.24539A-100000@rphc7> Uwe Tantz
<c4037@rphc1.physik.uni-regensburg.de> writes:
|> When I wrote a matrix-type container using Borland C++ 3.1, I also added
|> an
|> operator[] (int x, int y)
|> this allowed me to cache matrix elements easily at matrix-level. (I also
|> found the syntax more convenient a[x,y] instead of a[x][y]).
This sounds like a serious bug in Borland C++. In all compilers, the
expression `a[ x , y ]' is (or should be) defined, and has a definite
meaning (for user defined types): `a.operator[]( (x , y) )'. Note the
additional parentheses: operator[] takes a single parameter. `x' is
evaluated before y, and the results of this evaluation are discarded.
(Presumably, the expression `x' will have some side effects.
Otherwise, the expression is useless.)
Allowing `operator[]( int , int )' to be defined is a permitted
extension (I believe); calling it in the case of `a[ x , y ]' is
illegal, and will no doubt break certain code. (I would consider such
code very poorly written on stylistic grounds, but it is certainly
legal.) Given that `operator[]( int , int )' can only be called
explicitly (and not as a result of using a [] operator), and that this
is almost surely *not* what the programmer wanted, I would consider
such an extension a poor quality of implementation.
|> however when I ported the program to Visual C++, the compiler only
|> allowed one argument for [] (BTW Sun's C++ as well).
|> Is there a reason for this restriction?
As above. In general, you can only redefine existing operators, not
invent new ones. Since the operator you want to overload doesn't
exist in the language, you cannot overload it.
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: Uwe Tantz <c4037@rphc1.physik.uni-regensburg.de>
Date: 1995/07/06 Raw View
When I wrote a matrix-type container using Borland C++ 3.1, I also added
an
operator[] (int x, int y)
this allowed me to cache matrix elements easily at matrix-level. (I also
found the syntax more convenient a[x,y] instead of a[x][y]).
however when I ported the program to Visual C++, the compiler only
allowed one argument for [] (BTW Sun's C++ as well).
Is there a reason for this restriction?
Uwe
+---------------------+--------------------------------------------------+
| Uwe-Krischna Tantz | Tel/Fax: +49 941 / 56 31 40 |
| Hackengaesschen 4 | EMail: uwe.tantz@physik.uni-regensburg.de |
| 93047 Regensburg | |
+---------------------+--------------------------------------------------+
Author: Adam Wiewiorka <a.wiewiorka@ic.ac.uk>
Date: 1995/07/07 Raw View
As far as I know by default the [] is used for passing an offset to a pointer.
For example:
a[b]
means
*(a+b)
In this case it is a binary operator and when redefined, it must be a
non-static
member funcion. As far as I know operator overloading does not permit any
redefinition of the number of arguments used with an operator. You cannot
change a binary operator into a ternary one. (Look up Stroustrup's C++ book).