Topic: Extension to operator []


Author: pic2105@iperbole.bologna.it (Stefano Macchiavelli)
Date: 1996/12/08
Raw View
Max TenEyck Woodbury <mtew@cds.duke.edu> wrote:

>Over a year ago someone suggested providing multi-dimensional
>by allowing a comma seperated list in place of the single
>value in operator [].

I like very much the
class c {
        ...
        operator[](T1,T2,T3);
        ...
};
...

        c x;
        ...

        i = x[t1,t2,t3];

syntax, so I am proposing this solution:

        1) the multi-dimensional operator[] interpretation is the preferred
           whenever ... it exists
           (a class HAVE one or plus definitions for it).

        2) in any other case, the comma operator interpretation is done.

This don't break any existing code (which class today have a definition
for an illlegal construct?), at the price of a little attention in
writing code for future class which have.

I am aware this don't solve the built-in types problem,
but the alternative is none operator[](,,).

------

For the contents of the thread, I think that the x[t1,t2,t3] is really
an improvment (non a cosmetical one) because:

        1) there is a substantially difference (in the user defined
           class types)

           x[t1,t2,t3] is a single function call

           x[t1][t2][t3] is a chain of calls, and (bad) there is the
    necessity of "artificial return types" to have the effect.

        2) there is no problem to obtain the previous effect of comma
           operator with x[(t1,t2,t3)]

However, for people like me, there is a lot of power in the language,
so we can obtain a "pseudo multi-dimensional operator[]" at expense of
a little of work.

1) define, like STL have pair<T1,T2>, triple<T1,T2,T3>,
   a set of structs _2<T1,T2> , _3<T1,T2,T3> , _4<T1,T2,T3,T4> an so
on
   (I suggest the arguments are pass-by-reference, not mandatory)

template <class T1,class T2> struct _2 {
        T1& _1_;
        T2& _2_;
        _2(T1& t1,T2& t2) T1(t1), T2(t2) {}
};
template <class T1,class T2,class T3> struct _3 : _2<T1,T2> {
        T3& _3_;
        _3(T1& t1,T2& t2) _2<T1,T2>(t1,t2), T3(t3) {}
};
...
(you can use macros, to automate generation of n+1 from n)

2) make a family of overloaded functions, like make_pair:

inline
template <class T1,class T2>
_2<T1,T2> _(T1& t1, T2& t2){ return _2<T1,T2>(t1,t2); }

inline
template <class T1,class T2,class T3>
_3<T1,T2,T3> _(T1& t1, T2& t2,T3& t3){ return _3<T1,T2,T3>(t1,t2,t3);
}

...

and enjoy!

You can now write:

class c {
        ...
        operator[](_3<T1,T2,T3>);
        operator[](_3<X,Y,Z = 0>);
        operator[](_2<A,B>);
        ...
};
...

        c x;
        ...

        i = x[_(t1,t2,t3)];

so, it is syntactic sugar, but ...
... the while statement is also (you can obtain with if-goto).


-Reasonable people try to adapt themselves to the world
-Unreasonable people try to adapt the world to themselves
-That's why all progress depends on unreasonable people
                                   George Bernard Shaw
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: claus@faerber.muc.de (=?ISO-8859-1?Q?Claus_Andr=E9_F=E4rber?=)
Date: 1996/12/10
Raw View
Stefano Macchiavelli <pic2105@iperbole.bologna.it> wrote:
> Max TenEyck Woodbury <mtew@cds.duke.edu> wrote:
>
> >Over a year ago someone suggested providing multi-dimensional
> >by allowing a comma seperated list in place of the single
> >value in operator [].
>
> I like very much the
> class c {
>         ...
>         operator[](T1,T2,T3);
>         ...
>
>         i = x[t1,t2,t3];

I think, i=x[t1][t2][t3]; would

a) break less code
b) be more consistent with the ond syntax

There's no reason, why you could not use this syntax with the
proposed multidimensional operator[].

--
Claus Andre Faerber <claus@faerber.muc.de>, <http://www.muc.de/~cfaerber/>
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1996/12/11
Raw View
Claus_Andre_Farber wrote:
> I think, i=x[t1][t2][t3]; would
>
> a) break less code
> b) be more consistent with the ond syntax
>
> There's no reason, why you could not use this syntax with the
> proposed multidimensional operator[].

Then what would (x[t1])[t2] mean ? Do you want to introduce a new
operator [][] ? => to introduce a new token ][ ?

I don't say that I am against that, but you realize that it's tricky.

Also I don't understand exactly what you are proposing: could you
discribe your idea more precisely ?

--

Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Albert Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1996/12/12
Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:

|>  Claus_Andre_Farber wrote:
|>  > I think, i=x[t1][t2][t3]; would
|>  >
|>  > a) break less code
|>  > b) be more consistent with the ond syntax
|>  >
|>  > There's no reason, why you could not use this syntax with the
|>  > proposed multidimensional operator[].
|>
|>  Then what would (x[t1])[t2] mean ? Do you want to introduce a new
|>  operator [][] ? => to introduce a new token ][ ?

I think what he is trying to propose is that:

IF
    the insertion of user defined operators would result in chained
    calls to operator[], e.g.:
     x.operator[]( t1 ).operator[]( t2 )
AND
    the type of x has an operator[] declared to use two parameters

THEN
    use the operator[] with two parameters, thus:
     x.operator[]( t1 , t2 )

This applies recursively for more than two arguments.

|>  I don't say that I am against that, but you realize that it's tricky.

And I won't say that I'm for it.  First, there is the unintuitive
behavior with the parentheses that you point out: it seems strange that
the parentheses wouldn't inhibit the chaining, but it would also seem
strange if "x[t1][t2] != (x[t1])[t2]".  And of course, there are
problems of binding: what do you do in the case of three indices, above,
if the type of x defines both a one parameter index and a two parameter
index (but not a three parameter version), and the return type of the
single parameter version defines a two parameter version?  (Perhaps
clearer: what do you do if both of the following expansions are
potentially legal:

    i = x.operator[]( t1 , t2 ).operator[]( t3 )
    i = x.operator[]( t1 ).operator[]( t2 , t3 )

In some, the idea has superficial appeal, but IMHO, is more trouble than
it is worth.

(It is also worth pointing out that this proposal really doesn't buy
much.  Typically, in a Matrix class, the operator[] will return a helper
class, with operator[] defined on it.  All the above proposal does is
save the author of the Matrix class a bit of typing.)

--
James Kanze         home:     kanze@gabi-soft.fr        +33 (0)3 88 14 49 00
                    office:   kanze@vx.cit.alcatel.fr   +33 (0)1 69 63 14 54
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
       -- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: feathers@icanect.net (Michael C. Feathers)
Date: 1996/11/30
Raw View
In article <32952f9b.4891825@news.atl.mindspring.com>,
   abell@atl.mindspring.com (Andrew C. Bell) wrote:
>clamage@taumet.eng.sun.com (Steve Clamage) wrote:
>>Next, as discussed here previously, the construct
>>        [ x, y ]
>>already has a meaning in C and C++: evaluate x, then evaluate y and
>>use the result as the index value. (That is, the comma operator is a
>>sequence point, unlike the comma separating actual function arguments.)
>
>But does anyone really ever actually do this?  Seriously, I consider
>myself (perhaps wrongly) an extremely competent C++ programmer, yet I
>didn't know before this discussion that [a,b] is legitimate C++ code,
>nor have I ever seen, much less used, such a construct, and if I saw
>it in a code review, I'd berate the programmer for using such an
>arcane form.  (Unless, of course, it was the obfuscated C++
>contest...)

Yes, but not all C++ programmers are people.  I've written compilers which
generate C++ code.  It's syntactic richness and wide platform base make it an
ideal target.

The preprocessor is another non-human C++ programmer.  I could easily imagine
using the comma operator in a macro to force work into a single expression
rather than over a series of statements; although I'd hope that anyone doing
that would enclose the whole expression in parentheses, but there are no
guarantees and there is a hell of a lot of code out there.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: tkunert@rcs7.urz.tu-dresden.de (Thomas Kunert)
Date: 1996/12/01
Raw View
Steve Clamage (clamage@taumet.eng.sun.com) wrote:
: In article 2D56@cds.duke.edu, Max TenEyck Woodbury <mtew@cds.duke.edu>
: writes:
: >Over a year ago someone suggested providing multi-demensional
: >by allowing a comma seperated list in place of the single
: >value in operator [].
: >

: Next, as discussed here previously, the construct
:         [ x, y ]
: already has a meaning in C and C++: evaluate x, then evaluate y and
: use the result as the index value. (That is, the comma operator is a
: sequence point, unlike the comma separating actual function arguments.)

: You would break code that depended on the standard meaning of the comma
: operator. Since the proposal adds no functionality to C++ and would break
: C compatibility, it is unlikely to be acceptable as a language change.

That's it!
I have wondered if it makes sense to overload 'operator,'
since I have learned the rules of overloading.
Here is the answer: If you do so you can have multi-dimensional
array using [] without redefining the language.

Unfortunately you cannot overload it for int, so
at least the first index in [a, b, c..] must be of a user-defined class.
I like all indices of the same type, so all must have some user-defined type.
Anything else the following example explains:




#include <iostream.h>

class Array1D;
class Array2D;

struct Index {
   int x;
   Index(int a) : x(a){}
};

struct Index2 {
   int x, y;
   Index2(const Index& a, const Index& b) : x(a.x), y(b.x){}
};

struct Index3 {
   int x, y, z;
   Index3(const Index2& a, const Index& b) : x(a.x), y(a.y), z(b.x){}
};

inline Index3 operator,(const Index2& a, const Index& b)
{
 return Index3( a, b );
}

inline Index2 operator,(const Index& a, const Index& b)
{
 return Index2( a, b );
}

class Array3D {
public:

   // This should be replaced by 'return some_data[a.x][a.y][a.z];'
   double operator[]( Index3& a ){ return a.x*100+a.y*10+a.z;}
   Array1D& operator[]( Index2& a ); // some 1-dim Subarray
   Array2D& operator[]( Index& a ); // some 2-dim Subarray
};

Array3D unfug;

int main()
{
   Index x=1;
   Index y=2;
   Index z=3;
   cout << unfug[x,y,z] << endl;
      // calls operator[]( Index3& );

   cout << unfug[y,7,4] << endl;
}

If you behave 'Index' like the ints, then you can use it without
a big loss of efficiency.

Thomas Kunert
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Julian Pardoe <pardoej@lonnds.ml.com>
Date: 1996/12/04
Raw View
J. Kanze wrote:
>
> abell@atl.mindspring.com (Andrew C. Bell) writes:
>
> > clamage@taumet.eng.sun.com (Steve Clamage) wrote:
> > >Next, as discussed here previously, the construct
> > >        [ x, y ]
> > >already has a meaning in C and C++: evaluate x, then evaluate y and
> > >use the result as the index value. (That is, the comma operator is a
> > >sequence point, unlike the comma separating actual function arguments.)
> >
> > But does anyone really ever actually do this?
>
> In C, at least, yes.  I've seen it, more than once.  Take a look at the
> expansion of some of the macros in the standard headers if you think
> that the comma operator is never used as such.  (Things like this also
> appear a lot in the C generated by cfront.)

I use the comma operator a lot, mainly because I consider
   while (ch = getchar (), ch != EOF)
nicer that
   while ((ch = getchar ()) != EOF)

This might be due to my experiences with Algol 68C (in which any
amount of code may appear between WHILE and DO).

I dislike forms like
   if ((f = fopen ("foo", "r")) != NULL)
because they make opening the file look like a side effect of testing
the condition -- i.e. the if is looks primary and the gopen secondary
whereas of course it's the other way around.

-- jP --
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: rmashlan@r2m.com (Robert Mashlan)
Date: 1996/11/24
Raw View
abell@atl.mindspring.com (Andrew C. Bell) wrote:

>clamage@taumet.eng.sun.com (Steve Clamage) wrote:
>>Next, as discussed here previously, the construct
>>        [ x, y ]
>>already has a meaning in C and C++: evaluate x, then evaluate y and
>>use the result as the index value. (That is, the comma operator is a
>>sequence point, unlike the comma separating actual function arguments.)
>
>But does anyone really ever actually do this?  Seriously, I consider
>myself (perhaps wrongly) an extremely competent C++ programmer, yet I
>didn't know before this discussion that [a,b] is legitimate C++ code,
>nor have I ever seen, much less used, such a construct, and if I saw
>it in a code review, I'd berate the programmer for using such an
>arcane form.  (Unless, of course, it was the obfuscated C++
>contest...)

You could probably use an inline function to replace this in C++, but
consider if you had something like this:

#ifdef DEBUG
#define LOGINDEX(idx)  log_index(idx), idx
#else
#define LOGINDEX(idx) idx
#endif
   ...
   v = array[ LOGINDEX(idx) ]


rm



---
Robert Mashlan  R2M Software  rmashlan@r2m.com
Internet Resources for Windows Developers http://www.r2m.com/windev/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Max TenEyck Woodbury <mtew@cds.duke.edu>
Date: 1996/11/24
Raw View
Steve Clamage wrote:
>
> In article 4891825@news.atl.mindspring.com, abell@atl.mindspring.com
> (Andrew C. Bell) writes:
> >clamage@taumet.eng.sun.com (Steve Clamage) wrote:
> >>Next, as discussed here previously, the construct
> >>        [ x, y ]
> >>already has a meaning in C and C++: evaluate x, then evaluate y and
> >>use the result as the index value. (That is, the comma operator is a
> >>sequence point, unlike the comma separating actual function arguments.)
> >
> >But does anyone really ever actually do this?  ...
>
> As I see it, the prospect of a rule change converting a valid C++
> program into a valid C++ program with a different meaning needs to
> be studied very carefully. A lot of code gets generated by programs
> instead of being hand-crafted by programmers. It is common in
> machine-generated programs to find lots of comma-expressions, because
> generating a comma-expression is often the most practical way to
> get a desired result. (For an example, look at the output of
> C++ compilers that generate C as their target language.)
>

The point about intermediate code is a good one, but doesn't it apply
more to C than to C++, at least at this point? Further, the worst that
the generator would have to do is introduce an extra set of parens to
assure that the correct interpretation was made.  Finally, the addition
was addressed to the C++ standard because it would only apply to a user
defined operator [].

> The safest language change is one which gives meaning to previously
> invalid constructs. Most of C++ represents this kind of change compared
> to C, and most of the extensions to C++ are of this kind. No working
> code is affected, but you are allowed to write new kinds of programs.
>
> Next best is to invalidate previously valid code. Some C++ changes
> fall into this category. Adding a new keyword can invalidate some
> existing programs. Disallowing implicit casts from void* to other
> pointer types was such a change compared to C. Breaking existing
> code isn't nice, but at least the programmer gets a positive
> notification at compile time that a change occurred.

A derivative of this proposal would be to dissallow comma
expressions as immediate operands of the [] operator as a way to
prepare for the introduction of multiple operands for the []
operator.  As I see it, it isn't absolutely necessary, but would
simplify the parsing.

> A "quiet change", where a valid program becomes a different valid
> program without notice, is not nice. There have been a few quiet
> changes in C++, but in all cases the benefit was judged to outweigh
> the disadvantages by a large margin, and in some cases, the old
> rule was not a good rule anyway.
>
> ...
>
> I have no objection to allowing multiple indexes to arrays, but
> IMHO that change should be added in a way so as not to break or
> change the meaning of existing code.

I beleive this change could be defined in a way that existing code
that did not declare either T::operator [] (int, int) or operator []
(T, int, int) would not have to be rewritten.  It would mess up the
already messy parsing rules, but it could be done.

Because of potential problems this extension might generate, I was
asking that a note about a possible direction of future development
be added to the standard.  That would not commit anyone to
implementing this proposal or anything like it, but would provide
the necessary ground work for its serious consideration several years
from now.

mtew@cds.duke.edu
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: wald@theory.lcs.mit.edu (David Wald)
Date: 1996/11/24
Raw View
In article <m3k9rck75d.fsf@gabi-soft.fr> kanze@gabi-soft.fr (J. Kanze)
writes:
>abell@atl.mindspring.com (Andrew C. Bell) writes:
>> clamage@taumet.eng.sun.com (Steve Clamage) wrote:
>> >Next, as discussed here previously, the construct
>> >        [ x, y ]
>> >already has a meaning in C and C++:...
>>
>> But does anyone really ever actually do this?
...
>All of the uses I've seen have been in macros, and even there, it isn't
>that frequent.  The case generally occurs because you want the macro to
>look like a function returning a value.

But those macros had better be parenthesized, or they're already
broken.  If they're not parenthesized, they can't be used as arguments
to functions.

I'm not particularly inclined to defend this proposal, but I'm having
trouble coming up with any real code which would be broken by it.
Then again, who knows what evil lurks in the hearts of automatic code
generators?

-David
--
============================================================================
David Wald      http://theory.lcs.mit.edu/~wald/     wald@theory.lcs.mit.edu
============================================================================
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Max TenEyck Woodbury <mtew@cds.duke.edu>
Date: 1996/11/25
Raw View
Robert Mashlan wrote:
>
> ...
>
> You could probably use an inline function to replace this in C++, but
> consider if you had something like this:
>
> #ifdef DEBUG
> #define LOGINDEX(idx)  log_index(idx), idx

  #define LOGINDEX(idx)  (log_index(idx), idx)

> #else
> #define LOGINDEX(idx) idx
> #endif
>    ...
>    v = array[ LOGINDEX(idx) ]
>
> rm
>

As noted, this is easily fixed, but it does represent enough of a problem
that some ground work will have to be laid if the [] operator is ever to
take multiple operands in the future.  Is there enough interest to lay that
ground work now?

mtew@cds.duke.edu


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Micha Berger <aishdas@haven.ios.com>
Date: 1996/11/26
Raw View
Claus Andr=E9 F=E4rber <claus@faerber.muc.de> wrote:
: OK, OK: a[x][y] could be treated as (a[x])[y] or a([x][y]), we =20
: would need a rule that the operator[] which takes as many []s as =20
: possible is to be taken first.

With this rule, we could revert back to the original a[x,y] proposal.

If a::operator[](x,y) exists, parse it as that, otherwise, treat it as
a single argument using the comma operator.

This won't break any existing code, since a::operator[](x,y) can't exist
in existing code.

This also raises the Q of making an operator*+(a,b,c) which would be
/really/ useful in making efficient matrix mathematics code.

--=20
Micha Berger 201 916-0287        Help free Ron Arad, held by Syria 3692 d=
ays!
micha@aishdas.org                         (16-Oct-86 - 26-Nov-96)
<a href=3Dnews:alt.religion.aishdas>Orthodox Judaism: Torah, Avodah, Ches=
sed</a>
<a href=3Dhttp://aishdas.org>AishDas Society's Home Page</a>


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Max TenEyck Woodbury <mtew@cds.duke.edu>
Date: 1996/11/21
Raw View
Alexandre Oliva wrote:
>
> Max TenEyck Woodbury writes:
>
> > Over a year ago someone suggested providing multi-demensional
> > by allowing a comma seperated list in place of the single
> > value in operator [].
>
> This might break existing code.
>
> int x[5][3];
> void foo() { cout << x[2,1] << endl; }
>
> What does x[2,1] mean?
>
> a) The comma is the comma operator, that evaluates the left
> expression, discards its result, and the evaluates the right one.  In
> this case, it could have been written x[1], whose type is int [3].
> The output would be the value of the pointer to x[1][0].
>
> b) The comma denotes multi-dimensional array evaluation, so it could
> have been written x[2][1]. It has type int, and the output would be
> zero unless x[2][1] had been changed before invoking foo().
>
> So, which would the rules be for avoiding such ambiguity?  Deciding
> always for (a) would be removing this feature, because it would never
> be usable.  Deciding always for (b) would break existing code.  It
> might be decided to try to guess which meaning to choose from the
> expected type of the expression, but this is not always feasible,
> especially when there are overloaded functions and templates.
>

(b) would only be a possibility if an appropriate operator [] was
declared. For existing code, there would be no such declaration so
interpretation (a) would be implied and no existing code would be
broken.  As noted in my reply to Steve, additional rules might be
introduced to clarify the syntactic/semantic boundry and those
rules might cause the problem you suggest. Also note that the
example given, while currently precisely defined, is probably not
doing what the author intended.

> > Would it be reasonable for some compiler to provide an
> > optional language extension that would allow this as an
> > alternate syntax?
>
> As far as it is not enabled by default, compilers can do whatever they
> want, and probably there would be a lot of programmers who might like
> this feature, but some template libraries might break in this new
> configuration for using comma operators in array subscripts.
>

How would it break a template library?

> > The original suggestion was dismissed as 'mere syntactic
> > sugar'.
>
> And it actually is mere syntactic sugar, no matter what you say.  If
> there is one equivalent way to express the same, it is just syntactic
> sugar, it does not add anything to the power of the language.
>

I beleive someone showed that any program could be implemented with
only the assignment operator, the exclusive or operator, a branch on
zero and appropriate constants.  By your argument, a language with
only those elements is as powerful as C++.  Sorry, but I don't buy
that and I don't think most other people would buy it either...

> > However, I think there might be a practical effect of such a
> > change. The current syntax requires that multiple applications of
> > operator [] always be evaluated left to right.  With a comma
> > seperated list syntax, the order of evaluation is more open and
> > would allow the operator designer and compiler more options to
> > produce optimal code. In other words, the current syntax
> > overspecifies the operation to be performed and the alternate syntax
> > specifically does not.
>
> I could not find such requirement in the DWP.  It is true that
> operator [] groups left-to-right, but grouping has nothing to do with
> order of evaluation.  Smart compilers may optimize whatever they can
> between sequence points, and, AFAIK, there's not a sequence point
> related to subscript evaluation.
>

Ok, so my phrasing was lamentably loose...

> However, if you're talking about evaluation of user-defined operator
> [], you are right in assuming that they will be evaluated
> left-to-right, but not that their operands have to be evaluated left
> to right.  I mean:
>
> struct foo { foo& operator [](int) const; };
> int baz(), buz(), biz();
> void bark(int, int, int)
> void bar() {
>   bark(baz(), buz(), biz());
>   foo x;
>   x[baz()][buz()][biz()];
>   // x[baz(),buz(),biz()];
> }
>
> AFAIK, there's no requirement that baz() has to be evaluated before
> buz(), no matter it is a function argument or an array subscript.
> However, in the case of array subscript, the result of baz() will be
> USED before the result of buz().
>
> Besides, the suggested syntax (commented out), as it looks very much
> like usage of the comma operator, it gives an idea of order of
> evaluation (as the comma operator establishes sequence points), so its
> counterintuitive to allow the compiler to evaluate them in any
> different sequence than the left-to-right one.

You haven't defined operator [].  That was one of the (implied?)
requirements in my suggestion.

mtew@cds.duke.edu


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Max TenEyck Woodbury <mtew@cds.duke.edu>
Date: 1996/11/22
Raw View
Steve Clamage wrote:
>
> In article 2D56@cds.duke.edu, Max TenEyck Woodbury <mtew@cds.duke.edu>
> writes:
> >Over a year ago someone suggested providing multi-demensional
> >by allowing a comma seperated list in place of the single
> >value in operator [].
[some quoting snipped. -mod]
> >The original suggestion was dismissed as 'mere syntactic
> >sugar'. However, I think there might be a practical effect
> >of such a change. The current syntax requires that multiple
> >applications of operator [] always be evaluated left to
> >right. With a comma seperated list syntax, the order of
> >evaluation is more open and would allow the operator
> >designer and compiler more options to produce optimal
> >code. In other words, the current syntax overspecifies
> >the operation to be performed and the alternate syntax
> >specifically does not.
>
> Taking your last point first, writing
>         m[e1][e2][e3]
> implies nothing about the order of evaluation of e1, e2, and e3.
> That is, the [] operator is not a sequence point. You need some
> other reason for wanting such a change in the language.

Sorry, but that is not correct, or rather it misses the point.
It has to produce the same results as a left to right evaluation
and the operator designer has very little control over the
details.

> Next, as discussed here previously, the construct
>         [ x, y ]
> already has a meaning in C and C++: evaluate x, then evaluate y and
> use the result as the index value. (That is, the comma operator is a
> sequence point, unlike the comma separating actual function arguments.)
>

Yes, it does, just as strlen( (a,b) ); has a meaning.

> You would break code that depended on the standard meaning of the comma
> operator. Since the proposal adds no functionality to C++ and would break
> C compatibility, it is unlikely to be acceptable as a language change.

This does NOT follow from the previous comment. The new meaning would
only apply to a new operator [] definitions in new code.  Adding a
new operator [] to existing code might have unforeseen consequences,
but that has always been a possibility with any user written code.

> Another point which isn't clear from your suggestion: Are you
> suggesting that operator[] be allowed to take any number of
> arguments, as in
>         template class Matrix3D<class T> {
>                 ...
>                 T& operator[](int i, int j, int k);
>         };
>         Matrix3D<double> m(10, 10, 10); // 10x10x10 matrix
>         m(1,2,3) = 99.9;

Not quite. m(1,2,3) can be done now if you're careful. That requires
an operator () definition.  I was thinking of m[1,2,3] = 99.9;

> Or were you suggesting no change to operator[], but that
>         m(1,2,3)
> would be only a shorthand for
>         m[1][2][3]

No. Not the shorthand. It would have to be a delibrate and seperate
declaration as in your previous example.

> If you are suggesting the former, that is not a trivial change to the
> language, and if you wrote code that depended on a local compiler
> extension to allow multiple arguments to operator[], you would have
> to do considerable rewriting to move the code to a standard compiler.

Yes, unless it was adopted into a later version of the standard...
However, I'm not sure I agree with your characterization of the size
of the change.  It basically duplicates the effect of operator ()
but is less likely to cause confusion with constructor syntax.

This does tie back to your point about the comma operator. This
addition could cause some bluring of the line between syntactic
and semantic processing. There might be an inclination to
restore that distinction by excluding comma operator expressions
from being immediate operands of operator [], just as they are
excluded from being immediate operands of calling sequences.
THAT change might break some existing code, but it also raises
the question -- how much of the code with comma operator
expressions as operands to operator [] is in fact already
unintentionally broken? It certainly has a very high potential
for being misunderstood!

> If you are suggesting only the latter (shorthand notation), the benefit
> is miniscule, IMHO, and would not justify breaking any existing code.

The shorthand was NOT what I intended. That possibility has so many
potential problems, I didn't consider it as a reasonable interpretation
of what I suggested.  I'm glad you brought it up, but only so that it
can be properly quashed.

mtew@cds.duke.edu
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1996/11/22
Raw View
In article 6846@cds.duke.edu, Max TenEyck Woodbury <mtew@cds.duke.edu> writes:
>Alexandre Oliva wrote:
>>
>> Max TenEyck Woodbury writes:
>>
>> > Over a year ago someone suggested providing multi-demensional
>> > by allowing a comma seperated list in place of the single
>> > value in operator [].
>>
>> This might break existing code.
>>
>> int x[5][3];
>> void foo() { cout << x[2,1] << endl; }
>>
>> What does x[2,1] mean?
>>
>> a) The comma is the comma operator, that evaluates the left
>> expression, discards its result, and the evaluates the right one.  In
>> this case, it could have been written x[1], whose type is int [3].
>> The output would be the value of the pointer to x[1][0].
>>
>> b) The comma denotes multi-dimensional array evaluation, so it could
>> have been written x[2][1]. It has type int, and the output would be
>> zero unless x[2][1] had been changed before invoking foo().
>>
>> So, which would the rules be for avoiding such ambiguity?  Deciding
>> always for (a) would be removing this feature, because it would never
>> be usable.  Deciding always for (b) would break existing code.  It
>> might be decided to try to guess which meaning to choose from the
>> expected type of the expression, but this is not always feasible,
>> especially when there are overloaded functions and templates.
>>
>
>(b) would only be a possibility if an appropriate operator [] was
>declared. For existing code, there would be no such declaration so
>interpretation (a) would be implied and no existing code would be
>broken.

Not so. The example above is currently valid C++. If you change the
rules and add a T::operator[](int,int), the  code is still valid, but
has a completely different meaning. That is probably the worst way to
break code.

>  .... Also note that the
>example given, while currently precisely defined, is probably not
>doing what the author intended.

A rather sweeping statement. How would you know?

In any case, a language change that gives a different meaning to
previously-valid syntax is bound to create more confusion, even
(or especially) among experienced C++ programmers, than not
introducing the change.

If we were designing a language from scratch, built-in multi-dimensional
arrays would be worth serious consideration as a language feature. In
this case we would be adding features to an existing language and changing
the meaning of existing constructs. You don't want to do that lightly.
There should be a compensating significant increase in language power
or expressiveness.
---
Steve Clamage, stephen.clamage@eng.sun.com




[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/11/22
Raw View
>>>>> "SC" == Steve Clamage <clamage@taumet.eng.sun.com> writes:
[...]
SC> In any case, a language change that gives a different meaning to
SC> previously-valid syntax is bound to create more confusion, even
SC> (or especially) among experienced C++ programmers, than not
SC> introducing the change.

SC> If we were designing a language from scratch, built-in
SC> multi-dimensional arrays would be worth serious consideration as a
SC> language feature. In this case we would be adding features to an
SC> existing language and changing the meaning of existing
SC> constructs. You don't want to do that lightly.  There should be a
SC> compensating significant increase in language power or
SC> expressiveness.

(Note: I'm not trying to propose an addition to the language; just
       observing what might be an alternative).

Rather than trying to use multiple arguments `inside subscript brackets'
(which causes a clash ith the comma-operator), would it be possible to
provide a multiple-argument operator[] which is accessed through the
usual ``cascaded-[] syntax''.

E.g.:

 struct Array2D {
    double& operator[](int r, int c) { return a_[r*c_+c]; }
    // ...
 };

 void f() {
    Array2D a(m, n);
    cout << a[m-1][n-1]; // calls operator[](int, int)
    cerr << a[m-1]; // Error
    // ...
 }

This would among other things require that operator[] has a fixed
number of arguments per class.

What are the technical problems with such a feature?

 Daveed
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: abell@atl.mindspring.com (Andrew C. Bell)
Date: 1996/11/22
Raw View
clamage@taumet.eng.sun.com (Steve Clamage) wrote:
>Next, as discussed here previously, the construct
>        [ x, y ]
>already has a meaning in C and C++: evaluate x, then evaluate y and
>use the result as the index value. (That is, the comma operator is a
>sequence point, unlike the comma separating actual function arguments.)

But does anyone really ever actually do this?  Seriously, I consider
myself (perhaps wrongly) an extremely competent C++ programmer, yet I
didn't know before this discussion that [a,b] is legitimate C++ code,
nor have I ever seen, much less used, such a construct, and if I saw
it in a code review, I'd berate the programmer for using such an
arcane form.  (Unless, of course, it was the obfuscated C++
contest...)

If a proposed language change breaks a legal but almost never used
construct for a reasonable modification (since () can take multiple
args, it seems [] should be able to do so also), I wouldn't consider
it to be that much of a strike against the change.

Then again, I haven't had millions of C++ users watching everything I
might do...

Andrew Bell
abell@mindspring.com



[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: christian.bau@isltd.insignia.com (Christian Bau)
Date: 1996/11/23
Raw View
In article <32952f9b.4891825@news.atl.mindspring.com>,
abell@atl.mindspring.com (Andrew C. Bell) wrote:

> clamage@taumet.eng.sun.com (Steve Clamage) wrote:
> >Next, as discussed here previously, the construct
> >        [ x, y ]
> >already has a meaning in C and C++: evaluate x, then evaluate y and
> >use the result as the index value. (That is, the comma operator is a
> >sequence point, unlike the comma separating actual function arguments.)
>
> But does anyone really ever actually do this?  Seriously, I consider
> myself (perhaps wrongly) an extremely competent C++ programmer, yet I
> didn't know before this discussion that [a,b] is legitimate C++ code,
> nor have I ever seen, much less used, such a construct, and if I saw
> it in a code review, I'd berate the programmer for using such an
> arcane form.  (Unless, of course, it was the obfuscated C++
> contest...)
>
> If a proposed language change breaks a legal but almost never used
> construct for a reasonable modification (since () can take multiple
> args, it seems [] should be able to do so also), I wouldn't consider
> it to be that much of a strike against the change.

You might check that while

   1+2 1*2 1-2 etc

are considered to be integral constant expressions, quite surprisingly

   1,2

is not. I am quite sure that the reason for this is that a declaration

   int a [1,2];

should produce a syntax error, and should definitely not be the same as
"int a [2];".

One thing that always surprises me is that attitude that "no reasonable
programmer would do such a thing". Whatever you believe is a stupid thing
to do, someone will have code that does it and will have perfectly good
reasons to do it. Why shouldnt I write for example

   a [tmp = complicated_expression (), tmp*tmp+tmp+1];
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/11/23
Raw View
>>>>> "AB" == Andrew C Bell <abell@atl.mindspring.com> writes:
AB> clamage@taumet.eng.sun.com (Steve Clamage) wrote:
>> Next, as discussed here previously, the construct
>> [ x, y ]
>> already has a meaning in C and C++: evaluate x, then evaluate y and
>> use the result as the index value. (That is, the comma operator is a
>> sequence point, unlike the comma separating actual function arguments.)

AB> But does anyone really ever actually do this?

Anyone, I don't know. But `anything': yes. Compilers using C as an
intermediate language routinely rely on comma-expressions that are
inserted about anywhere you might find an expression.

AB> Seriously, I consider
AB> myself (perhaps wrongly) an extremely competent C++ programmer, yet I
AB> didn't know before this discussion that [a,b] is legitimate C++ code,
AB> nor have I ever seen, much less used, such a construct, and if I saw
AB> it in a code review, I'd berate the programmer for using such an
AB> arcane form.  (Unless, of course, it was the obfuscated C++
AB> contest...)

Well, I was told that during job-interviews here on campus this was
almost exactly the question asked by one rather large software-firm to
anyone who put `proficient in C++' on their resume. Although I agree
that this is not a very revealing issue, I was surprised at how little
this is known (the comma-operator is no more arcane IMO than, say, the
function-call operator or the ternary ?: operator; also, it stands out
by being at an extreme end of the operator precedence table.)

 Daveed
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: abell@atl.mindspring.com (Andrew C. Bell)
Date: 1996/11/23
Raw View
christian.bau@isltd.insignia.com (Christian Bau) wrote:
>One thing that always surprises me is that attitude that "no reasonable
>programmer would do such a thing".

Looking at my post, I would say I *asked* "does any reasonable
programmer ever do such a thing?"  People have been saying it can be
done, without saying whether they actually use it.

>Whatever you believe is a stupid thing
>to do, someone will have code that does it and will have perfectly good
>reasons to do it. Why shouldnt I write for example
>
>   a [tmp = complicated_expression (), tmp*tmp+tmp+1];

Because this is in no way different from

 tmp = complicated_expression();
 a[tmp*tmp+tmp+1];

and the first form leads to more confusion with the 95% of us who
aren't C++ gods.  And 90% of the time, you need a new variable for tmp
anyway when you need to do this.

Andrew Bell
abell@mindspring.com
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1996/11/23
Raw View
In article 4891825@news.atl.mindspring.com, abell@atl.mindspring.com
(Andrew C. Bell) writes:
>clamage@taumet.eng.sun.com (Steve Clamage) wrote:
>>Next, as discussed here previously, the construct
>>        [ x, y ]
>>already has a meaning in C and C++: evaluate x, then evaluate y and
>>use the result as the index value. (That is, the comma operator is a
>>sequence point, unlike the comma separating actual function arguments.)
>
>But does anyone really ever actually do this?  ...

As I see it, the prospect of a rule change converting a valid C++
program into a valid C++ program with a different meaning needs to
be studied very carefully. A lot of code gets generated by programs
instead of being hand-crafted by programmers. It is common in
machine-generated programs to find lots of comma-expressions, because
generating a comma-expression is often the most practical way to
get a desired result. (For an example, look at the output of
C++ compilers that generate C as their target language.)

The safest language change is one which gives meaning to previously
invalid constructs. Most of C++ represents this kind of change compared
to C, and most of the extensions to C++ are of this kind. No working
code is affected, but you are allowed to write new kinds of programs.

Next best is to invalidate previously valid code. Some C++ changes
fall into this category. Adding a new keyword can invalidate some
existing programs. Disallowing implicit casts from void* to other
pointer types was such a change compared to C. Breaking existing
code isn't nice, but at least the programmer gets a positive
notification at compile time that a change occurred.

A "quiet change", where a valid program becomes a different valid
program without notice, is not nice. There have been a few quiet
changes in C++, but in all cases the benefit was judged to outweigh
the disadvantages by a large margin, and in some cases, the old
rule was not a good rule anyway.

Probably the least controversial quiet change was the introduction of //
comments in C++, now being adopted in C as well. Some odd programs
 i = j//* divide j by -2 */
     -2;
are quietly changed -- (j/-2) becomes (j-2) -- but those should be
very rare indeed, and the benefit of // comments is judged to be large.
(Mechanically generated programs tend to have extra space between
tokens rather than less space, because omitting spaces is more likely
to run tokens together incorrectly, and extra space is never wrong. A
space between '/' and '/*' eliminates the quiet change.)

Probably the most controversial quiet change was changing the scope
of a variable defined in a 'for' header:
 for( int j = 0; ... ) ...
The original rule, that the j was placed in the enclosing scope,
causes serious ambiguities, and the old rule was tinkered with many
times trying to find a satisfactory solution to problems like the
scope of k in this example that has no curly braces:
 for( int j = 0; ... )
     for( int k = 0; ... )
  g(j,k);
The new rule, that the scope of the variable extends only to the end
of the controlled statement, has some nice properties, but breaks
existing code. Most of the time, the old code becomes invalid and
you get an error message from the compiler, and is easily fixed.
On rare occasions, you can get a quiet change. The C++ Committee
decided to accept the quiet changes because they were judged to be
very rare, unlikely to be machine-generated (such code tends to use
extra braces rather than fewer braces), and because no good
fix to the old rule could be found.

I have no objection to allowing multiple indexes to arrays, but
IMHO that change should be added in a way so as not to break or
change the meaning of existing code.
---
Steve Clamage, stephen.clamage@eng.sun.com
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1996/11/23
Raw View
Max TenEyck Woodbury writes:

>> > Would it be reasonable for some compiler to provide an
>> > optional language extension that would allow this as an
>> > alternate syntax?
>>
>> As far as it is not enabled by default, compilers can do whatever they
>> want, and probably there would be a lot of programmers who might like
>> this feature, but some template libraries might break in this new
>> configuration for using comma operators in array subscripts.
>>

> How would it break a template library?

template <class T, class U>
U& foo(T& bar, int i, int j) { return bar[i,j]; }

This would have different meaning if bar[i,j] were not the same as
bar[j].  This is just a trivial example, but, if some coder had used
comma as the comma operator in a template definition, it would break
if the meaning of that comma changed.

>> > The original suggestion was dismissed as 'mere syntactic
>> > sugar'.
>>
>> And it actually is mere syntactic sugar, no matter what you say.  If
>> there is one equivalent way to express the same, it is just syntactic
>> sugar, it does not add anything to the power of the language.
>>

> I beleive someone showed that any program could be implemented with
> only the assignment operator, the exclusive or operator, a branch on
> zero and appropriate constants.  By your argument, a language with
> only those elements is as powerful as C++.  Sorry, but I don't buy
> that and I don't think most other people would buy it either...

By power of the language, I did not only mean what CAN be done, but
HOW MUCH you have to write to achieve that.  It is known that you only
need lambda expressions, but I'd not write a program starting from
scratch, using only lambda expressions.  The point is expressiveness,
and having [i,j] to mean the same as [i][j] does not add anything to
power nor to expressiveness, so it is unnecessary.

However, overloading operator[] to be able to get several arguments,
as David Vandevoorde wrote in another message, would be fine, and
would not break code, as long as the code is written [i][j], and would
not be that hard to implement (I think).

>> struct foo { foo& operator [](int) const; };
[snip]

> You haven't defined operator [].  That was one of the (implied?)
> requirements in my suggestion.

You mean I hadn't defined operator[](int, int, int)const, right?
Well, I did not, as it is not valid C++, and I did not think the
proposal was for extending the language in this sense.

Anyway, I like the idea of operator[](int, int), it would be nice for
defining matrix without having to rely on some matrix_line class.

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br
Universidade Estadual de Campinas, SP, Brasil
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: claus@faerber.muc.de (=?ISO-8859-1?Q?Claus_Andr=E9_F=E4rber?=)
Date: 1996/11/24
Raw View
Hallo Andrew, hallo everybody,

Andrew C. Bell <abell@atl.mindspring.com> wrote on 23 Nov 96:
> christian.bau@isltd.insignia.com (Christian Bau) wrote:
> >One thing that always surprises me is that attitude that "no
> >reasonable programmer would do such a thing".
>
> Looking at my post, I would say I *asked* "does any reasonable
> programmer ever do such a thing?"  People have been saying it can
> be done, without saying whether they actually use it.

It really could be used in dozens of programs without the =20
programmer even knowing about it.
Maybe, it is in a #define'd macro the programmer used. Especially =20
those often contain code making use of "," and "?:".

> > Why shouldnt I write for example
> >
> >   a [tmp =3D complicated_expression (), tmp*tmp+tmp+1];
>
> Because this is in no way different from
> and the first form leads to more confusion with the 95% of us who
> aren't C++ gods.  And 90% of the time, you need a new variable for
> tmp anyway when you need to do this.

Well, the question is NOT whether one SHOULD use it, but if it IS =20
used. And I suspect that it is in much more code than you think.

--=20
Claus Andr=E9 F=E4rber <claus@faerber.muc.de>, <http://www.muc.de/~cfaerb=
er/>
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: claus@faerber.muc.de (=?ISO-8859-1?Q?Claus_Andr=E9_F=E4rber?=)
Date: 1996/11/24
Raw View
Hallo David, hallo everybody,

David Vandevoorde <vandevod@cs.rpi.edu> wrote on 22 Nov 96:

> Rather than trying to use multiple arguments `inside subscript
> brackets' (which causes a clash ith the comma-operator), would it
> be possible to provide a multiple-argument operator[] which is
> accessed through the usual ``cascaded-[] syntax''.

This is what I wanted to suggest right now.

> This would among other things require that operator[] has a fixed
> number of arguments per class.

Huh, no. What is the problem with:

> struct Array2D {
>       double& operator[](int r, int c) { return a_[r*c_+c]; };
        double* operator[](int r) { return a_[r*c_]; };
>    // ...
>  };

> void f() {
>       Array2D a(m, n);
>       cout << a[m-1][n-1];    // calls operator[](int, int)
>       cerr << a[m-1];         // calls operator[](int)
>       // ...
> }

OK, OK: a[x][y] could be treated as (a[x])[y] or a([x][y]), we =20
would need a rule that the operator[] which takes as many []s as =20
possible is to be taken first.

> What are the technical problems with such a feature?

The only problem I can think of: How can a compiler decide if

  foo::operator[]( int a, int b);

is meant to be an "operator[] for int visible in the scope of foo" =20
or an "2 dimensional operator[] for foo"?

Maybe "operator[][](...)".

--=20
Claus Andr=E9 F=E4rber <claus@faerber.muc.de>, <http://www.muc.de/~cfaerb=
er/>
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/11/24
Raw View
abell@atl.mindspring.com (Andrew C. Bell) writes:

> clamage@taumet.eng.sun.com (Steve Clamage) wrote:
> >Next, as discussed here previously, the construct
> >        [ x, y ]
> >already has a meaning in C and C++: evaluate x, then evaluate y and
> >use the result as the index value. (That is, the comma operator is a
> >sequence point, unlike the comma separating actual function arguments.)
>
> But does anyone really ever actually do this?

In C, at least, yes.  I've seen it, more than once.  Take a look at the
expansion of some of the macros in the standard headers if you think
that the comma operator is never used as such.  (Things like this also
appear a lot in the C generated by cfront.)

> Seriously, I consider
> myself (perhaps wrongly) an extremely competent C++ programmer, yet I
> didn't know before this discussion that [a,b] is legitimate C++ code,
> nor have I ever seen, much less used, such a construct, and if I saw
> it in a code review, I'd berate the programmer for using such an
> arcane form.  (Unless, of course, it was the obfuscated C++
> contest...)

All of the uses I've seen have been in macros, and even there, it isn't
that frequent.  The case generally occurs because you want the macro to
look like a function returning a value.

Since C++ has inline functions, I would hope that it wouldn't occur.
But I can imagine people maintaining common header files for C and C++,
with some tricky macros.

--
James Kanze          +33 3 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
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Max TenEyck Woodbury <mtew@cds.duke.edu>
Date: 1996/11/20
Raw View
Over a year ago someone suggested providing multi-demensional
by allowing a comma seperated list in place of the single
value in operator [].

With the following clearly understood:

1. It is currently too late to change the current version of
   the standard, and

2. It was too late to change the standard even when the
   request was originally proposed.

Would it be reasonable for some compiler to provide an
optional language extension that would allow this as an
alternate syntax?

The original suggestion was dismissed as 'mere syntactic
sugar'. However, I think there might be a practical effect
of such a change. The current syntax requires that multiple
applications of operator [] always be evaluated left to
right. With a comma seperated list syntax, the order of
evaluation is more open and would allow the operator
designer and compiler more options to produce optimal
code. In other words, the current syntax overspecifies
the operation to be performed and the alternate syntax
specifically does not.

mtew@cds.duke.edu



[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1996/11/21
Raw View
In article 2D56@cds.duke.edu, Max TenEyck Woodbury <mtew@cds.duke.edu> writes:
>Over a year ago someone suggested providing multi-demensional
>by allowing a comma seperated list in place of the single
>value in operator [].
>
>With the following clearly understood:
>
>1. It is currently too late to change the current version of
>   the standard, and
>
>2. It was too late to change the standard even when the
>   request was originally proposed.
>
>Would it be reasonable for some compiler to provide an
>optional language extension that would allow this as an
>alternate syntax?
>
>The original suggestion was dismissed as 'mere syntactic
>sugar'. However, I think there might be a practical effect
>of such a change. The current syntax requires that multiple
>applications of operator [] always be evaluated left to
>right. With a comma seperated list syntax, the order of
>evaluation is more open and would allow the operator
>designer and compiler more options to produce optimal
>code. In other words, the current syntax overspecifies
>the operation to be performed and the alternate syntax
>specifically does not.

Taking your last point first, writing
 m[e1][e2][e3]
implies nothing about the order of evaluation of e1, e2, and e3.
That is, the [] operator is not a sequence point. You need some
other reason for wanting such a change in the language.

Next, as discussed here previously, the construct
        [ x, y ]
already has a meaning in C and C++: evaluate x, then evaluate y and
use the result as the index value. (That is, the comma operator is a
sequence point, unlike the comma separating actual function arguments.)

You would break code that depended on the standard meaning of the comma
operator. Since the proposal adds no functionality to C++ and would break
C compatibility, it is unlikely to be acceptable as a language change.

Another point which isn't clear from your suggestion: Are you
suggesting that operator[] be allowed to take any number of
arguments, as in
 template class Matrix3D<class T> {
  ...
  T& operator[](int i, int j, int k);
 };
 Matrix3D<double> m(10, 10, 10); // 10x10x10 matrix
 m(1,2,3) = 99.9;

Or were you suggesting no change to operator[], but that
 m(1,2,3)
would be only a shorthand for
 m[1][2][3]

If you are suggesting the former, that is not a trivial change to the
language, and if you wrote code that depended on a local compiler
extension to allow multiple arguments to operator[], you would have
to do considerable rewriting to move the code to a standard compiler.

If you are suggesting only the latter (shorthand notation), the benefit
is miniscule, IMHO, and would not justify breaking any existing code.
---
Steve Clamage, stephen.clamage@eng.sun.com




[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1996/11/21
Raw View
Max TenEyck Woodbury writes:

> Over a year ago someone suggested providing multi-demensional
> by allowing a comma seperated list in place of the single
> value in operator [].

This might break existing code.

int x[5][3];
void foo() { cout << x[2,1] << endl; }

What does x[2,1] mean?

a) The comma is the comma operator, that evaluates the left
expression, discards its result, and the evaluates the right one.  In
this case, it could have been written x[1], whose type is int [3].
The output would be the value of the pointer to x[1][0].

b) The comma denotes multi-dimensional array evaluation, so it could
have been written x[2][1]. It has type int, and the output would be
zero unless x[2][1] had been changed before invoking foo().


So, which would the rules be for avoiding such ambiguity?  Deciding
always for (a) would be removing this feature, because it would never
be usable.  Deciding always for (b) would break existing code.  It
might be decided to try to guess which meaning to choose from the
expected type of the expression, but this is not always feasible,
especially when there are overloaded functions and templates.


> Would it be reasonable for some compiler to provide an
> optional language extension that would allow this as an
> alternate syntax?

As far as it is not enabled by default, compilers can do whatever they
want, and probably there would be a lot of programmers who might like
this feature, but some template libraries might break in this new
configuration for using comma operators in array subscripts.


> The original suggestion was dismissed as 'mere syntactic
> sugar'.

And it actually is mere syntactic sugar, no matter what you say.  If
there is one equivalent way to express the same, it is just syntactic
sugar, it does not add anything to the power of the language.

> However, I think there might be a practical effect of such a
> change. The current syntax requires that multiple applications of
> operator [] always be evaluated left to right.  With a comma
> seperated list syntax, the order of evaluation is more open and
> would allow the operator designer and compiler more options to
> produce optimal code. In other words, the current syntax
> overspecifies the operation to be performed and the alternate syntax
> specifically does not.

I could not find such requirement in the DWP.  It is true that
operator [] groups left-to-right, but grouping has nothing to do with
order of evaluation.  Smart compilers may optimize whatever they can
between sequence points, and, AFAIK, there's not a sequence point
related to subscript evaluation.

However, if you're talking about evaluation of user-defined operator
[], you are right in assuming that they will be evaluated
left-to-right, but not that their operands have to be evaluated left
to right.  I mean:

struct foo { foo& operator [](int) const; };
int baz(), buz(), biz();
void bark(int, int, int)
void bar() {
  bark(baz(), buz(), biz());
  foo x;
  x[baz()][buz()][biz()];
  // x[baz(),buz(),biz()];
}

AFAIK, there's no requirement that baz() has to be evaluated before
buz(), no matter it is a function argument or an array subscript.
However, in the case of array subscript, the result of baz() will be
USED before the result of buz().

Besides, the suggested syntax (commented out), as it looks very much
like usage of the comma operator, it gives an idea of order of
evaluation (as the comma operator establishes sequence points), so its
counterintuitive to allow the compiler to evaluate them in any
different sequence than the left-to-right one.


Regards,

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br
Universidade Estadual de Campinas, SP, Brasil


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]