Topic: operator[][][]


Author: gdr@cs.tamu.edu (Gabriel Thomas Dos Reis)
Date: Fri, 28 Jul 2006 19:20:10 GMT
Raw View
fgothamNO@SPAM.com (Frederick Gotham) writes:

| > My point was to come up with a way to define an operator[] that, given
| > N, takes N arguments; not a way to write by hand any sequence of []s.
|
|
| I'm not quite sure I understand, but do you mean something like:
|
|
|     int &operator[3](unsigned,unsigned,unsigned);
|
|     SomeType &operator[2](unsignd,unsigned);

why not the simplest

     int& operator[](int, int, int);
     int& operator[](int, int);

?

--
                                                        Gabriel Dos Reis
                                                         gdr@cs.tamu.edu
 Texas A&M University -- Department of Computer Science
 301, Bright Building -- College Station, TX 77843-3112

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: SeeWebsiteForEmail@erdani.org ("Andrei Alexandrescu (See Website For Email)")
Date: Fri, 28 Jul 2006 22:32:04 GMT
Raw View
Gene Bushuyev wrote:
> Creating proxies for rows and columns is necessary for completely independent
> reasons. Every general purpose matrix library has to do that.

I disagree, but passons.

> If performance is
> an issue, a not-so-sexy alternative of using a named function or operator(),
> which is free from all those problems, is readily available. So why create an
> operator[][][][] monstrosity for non-existing problem?

Because we want to have both efficiency and... sexiness?  ):o)


Andrei

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: SeeWebsiteForEmail@erdani.org ("Andrei Alexandrescu (See Website For Email)")
Date: Fri, 28 Jul 2006 23:41:55 GMT
Raw View
Bo Persson wrote:
> "Frederick Gotham" <fgothamNO@SPAM.com> skrev i meddelandet
>>Or do I detect sarcasm?
>
>
> Some.

I think we'd be typesafe to forget some specifics and focus on the
larger need, which is, as far as I understand, the need to specify
variable argument lists in a flexible manner. A step towards
generalization OP's question is:

template <class T, unsigned dims>
struct Matrix {
   Matrix(___ need exactly dims unsigned ints here ___);
   T& operator[](___ need exactly dims unsigned ints here ___);
   // or
   T& operator()(___ need exactly dims unsigned ints here ___);
   ...
};

I know there are workarounds, but they aren't as elegant and as
efficient as the true thing could be. What would the true thing look like?


Andrei

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "kanze" <kanze@gabi-soft.fr>
Date: Thu, 27 Jul 2006 09:58:11 CST
Raw View
Frederick Gotham wrote:
> kanze posted:

> > On the other hand, both C and C++ already have a syntax for
> > indexing "multiple dimension arrays": [i][j][k].  If at all
> > possible, a solution should be found which preserves this
> > notation.

> Operators are independant of each other. They're processed
> individually. If you use one particular operator in an
> expression, it doesn't alter the effect of any other operator
> which is present in the expression. I believe, however, that
> one exception was made -- where the addressof and dereference
> operators appear together. I'm not sure if it was the C
> committee or the C++ committee, but one of them decided that
> the following should be perfectly legal:

>     int array[5];

>     int *p = &array[5];

> Obviously, this becomes:

>     int *p = &( *(array + 5) );

> As you can see, the "pointer to one past last" is
> dereferenced, so this *should* invoke UB. But, because it has
> the addressof operator right behind it, the committee decided
> that they should cancel each other out to yield perfectly
> valid code.

The C committee decided that.  As far as I know, there is no
intention for the C++ to follow.  If you want to support that,
then you'd probably want the same thing to hold for iterators.
And for iterators, of course, the operators are user defined
functions, which are separate, and the validation (detection of
undefined behavior) takes place in the operator*() function of
the iterator.

> So that's an example of one operator altering the affect of
> another operator, and of how operators don't have to be
> independant of each other in an expression.

> Perhaps this should be done again -- where multiple pairs of
> square brackets appear together. They should be given special
> treatment, such that we can write an operator overload such as
> the following:

> class MyClass {
> protected:
>     int array[5][6][7];
>
> public:
>     int &operator[][][](unsigned const a,unsigned const b,unsigned const c)
>     {
>         return array[a][b][c];
>     }
> };

> When the compiler sees an expression of the type:

>     obj[1][2][3] = 5;

> It should:

>     (1) Look for an operator[][][]

> If that fails, it should:

>     (2) Look for an operator[][]

> If that fails, it should:

>     (3) Look for an operator[]

> It should keep scaling downwards until it finds a match. That
> way, no existing code would be broken.

I don't think there's any fundamental reason why it couldn't be
done.  But I don't see any need for it, either.  It's easy
enough to get the same effect already.

--
James Kanze                                           GABI Software
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Thu, 27 Jul 2006 17:26:53 GMT
Raw View
kanze posted:

> I don't think there's any fundamental reason why it couldn't be
> done.  But I don't see any need for it, either.  It's easy
> enough to get the same effect already.


The way of doing it at the moment is unnecessarily messy and inefficient, and
would be much improved upon if we could simply define multiple[] operators.

--

Frederick Gotham

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Thu, 27 Jul 2006 18:24:51 GMT
Raw View
Carl Barron posted:

> template <class T,size_t cols,size_t rows>
> class Matrix
> {
>    T  data[rows*cols];
> public:
>    struct subscript_proxy
>    {
>       T  *data;
>       int i;
>       subscript_proxy(T *a,int b):data(a),i(b){}
>       T & operator [] (int j) {return data[i+j];}
>    };
>    subscript_proxy operator [] (int i)
>    {
>       return subscript_proxy(data,i*cols);
>    }
> };
> or build an array of T*s in the ctor
>
> template<class T,size_t rows,size_t cols>
> class Matrix
> {
>    T  data[rows*cols];
>    T *row_start[rows];
> {
>    Matrix()
>    {
>       T *p = data;
>       for(int i=0;i!=rows;++i,p+=cols)
>          row_start[i] = p;
>    }
>    T * operator [] (int i) {return row_start[i];}
> };
>
> now  Matrix A;
>       x = A[i][j]   first calls Matrix::operator [](i) and then the
> operator [](j) [either the built in for double * , or
> subscript_proxy::operator [] depending on which of above
> implementations is used ]


Yes, I'm well aware of that method. (A recent post of mine:
http://groups.google.ie/group/comp.lang.c++/msg/78fa7e8bb91e8525?hl=en& )

Code would be a lot nicer (and would perform a lot better) if we could
simply define:

    T &operator[][][](unsigned,unsigned,unsigned);

--

Frederick Gotham

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: SeeWebsiteForEmail@erdani.org ("Andrei Alexandrescu (See Website For Email)")
Date: Thu, 27 Jul 2006 18:48:48 GMT
Raw View
Frederick Gotham wrote:
> Code would be a lot nicer (and would perform a lot better) if we could
> simply define:
>
>     T &operator[][][](unsigned,unsigned,unsigned);

That's true, but it's like being offered the proverbial fish and asking
for two more instead of asking for the proverbial fishing rod. The
"fishing rod" solution would allow defining operator[] with any
statically-known number of levels. This would allow easy and efficient
implementation of generic multidimensional vectors.

Andrei

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: spam@spamguard.com ("Gene Bushuyev")
Date: Thu, 27 Jul 2006 18:55:08 GMT
Raw View
"Frederick Gotham" <fgothamNO@SPAM.com> wrote in message
news:W36yg.11925$j7.320490@news.indigo.ie...
> kanze posted:
>
>> I don't think there's any fundamental reason why it couldn't be
>> done.  But I don't see any need for it, either.  It's easy
>> enough to get the same effect already.
>
>
> The way of doing it at the moment is unnecessarily messy and inefficient, and
> would be much improved upon if we could simply define multiple[] operators.
>


It's not messy, it reflects the organization of subscript-able classes (e.g.
matrix). Even if there were multiple [] operators, one's matrix library would be
incomplete without ways of defining classes for rows and columns, which in turn
must define operator[]. So the multiple [] operator wouldn't be used anyway.
There probably isn't a mathematical model of anything that would have a need for
multiple [] only and not also a need for single operator [].

--
Gene Bushuyev (www.gbresearch.com)
----------------------------------------------------------------
To see what is in front of one's nose needs a constant struggle ~ George Orwell

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Frederick Gotham <fgothamNO@SPAM.com>
Date: Thu, 27 Jul 2006 14:38:54 CST
Raw View
"Gene Bushuyev" posted:

> It's not messy, it reflects the organization of subscript-able classes
> (e.g. matrix). Even if there were multiple [] operators, one's matrix
> library would be incomplete without ways of defining classes for rows
> and columns, which in turn must define operator[].


Then go ahead and define operator[] for "row" and "column" -- the definition
of an operator[][] in "matrix" isn't stopping you from doing that.

--

Frederick Gotham

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: SeeWebsiteForEmail@erdani.org ("Andrei Alexandrescu (See Website For Email)")
Date: Thu, 27 Jul 2006 19:39:18 GMT
Raw View
Gene Bushuyev wrote:
> "Frederick Gotham" <fgothamNO@SPAM.com> wrote in message
> news:W36yg.11925$j7.320490@news.indigo.ie...
>
>>kanze posted:
>>
>>
>>>I don't think there's any fundamental reason why it couldn't be
>>>done.  But I don't see any need for it, either.  It's easy
>>>enough to get the same effect already.
>>
>>
>>The way of doing it at the moment is unnecessarily messy and inefficient, and
>>would be much improved upon if we could simply define multiple[] operators.
>>
>
>
>
> It's not messy, it reflects the organization of subscript-able classes (e.g.
> matrix). Even if there were multiple [] operators, one's matrix library would be
> incomplete without ways of defining classes for rows and columns, which in turn
> must define operator[]. So the multiple [] operator wouldn't be used anyway.
> There probably isn't a mathematical model of anything that would have a need for
> multiple [] only and not also a need for single operator [].

I agree with Frederick; it's messy. I remember having read an article on
implementing this technique. In spite of the author's valiant efforts,
the compiler was unable to see through and generate efficient code for
the multiple subscript. The net result was four times slower than the
not-so-sexy alternative, which puts the technique straight in the
useless bin - particularly since we're talking about matrix operations.

Andrei

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Thu, 27 Jul 2006 20:41:55 GMT
Raw View
> The "fishing rod" solution would allow defining operator[] with any
> statically-known number of levels.

I shudder to think that you gathered I was implying that only:

     operator[][][]

should be allowed, rather than any amount of them:

    operator[][][][]
    operator[][][]
    operator[][][][][]
    operator[][]

--

Frederick Gotham

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: v.Abazarov@comAcast.net ("Victor Bazarov")
Date: Thu, 27 Jul 2006 21:11:21 GMT
Raw View
"Frederick Gotham" <fgothamNO@SPAM.com> wrote...
>
>> The "fishing rod" solution would allow defining operator[] with any
>> statically-known number of levels.
>
> I shudder to think that you gathered I was implying that only:
>
>     operator[][][]
>
> should be allowed, rather than any amount of them:
>
>    operator[][][][]
>    operator[][][]
>    operator[][][][][]
>    operator[][]

How about this?  The definition syntax should allow having more than
one argument, and the utilisation syntax should check the number of
bracket pairs after the expression and reach for an overloaded operator
with the same number of arguments.  Like

    class C {
    public:
        int operator[](int a, char b) { return 42; } // 1
        char const* operator[](char const* s) { return s; } // 2
    };

    int main() {
        C c;
        c[22]['a']; // resolves to 1 rather than 2 - exact match
                    // calls     c.operator[](22,'a')
        c["abc"][1]; // resolves to 2 - closer match
                     // calls     c.operator[]("abc") and then
                     // indexes the resulting pointer
    }

Or am I completely missing the point here?  If so, I'm sorry.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: kst-u@mib.org (Keith Thompson)
Date: Thu, 27 Jul 2006 23:04:05 GMT
Raw View
fgothamNO@SPAM.com (Frederick Gotham) writes:
>> The "fishing rod" solution would allow defining operator[] with any
>> statically-known number of levels.
>
> I shudder to think that you gathered I was implying that only:
>
>      operator[][][]
>
> should be allowed, rather than any amount of them:
>
>     operator[][][][]
>     operator[][][]
>     operator[][][][][]
>     operator[][]

But that still implies that the number of levels is to some fixed
number, by the language requirements, but by what the author happened
to write.

If you provide me with separate overloadings for each of
    operator[][]
    operator[][][]
    operator[][][][]
    operator[][][][][]
then I can't use
    operator[][][][][][]

If you provide me with the tools to build any number of levels, I can
use as many levels as I need, not just as many levels as you thought I
would need.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center             <*>  <http://users.sdsc.edu/~kst>
We must do something.  This is something.  Therefore, we must do this.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: kst-u@mib.org (Keith Thompson)
Date: Fri, 28 Jul 2006 05:20:51 GMT
Raw View
kst-u@mib.org (Keith Thompson) writes:
> fgothamNO@SPAM.com (Frederick Gotham) writes:
>>> The "fishing rod" solution would allow defining operator[] with any
>>> statically-known number of levels.
>>
>> I shudder to think that you gathered I was implying that only:
>>
>>      operator[][][]
>>
>> should be allowed, rather than any amount of them:
>>
>>     operator[][][][]
>>     operator[][][]
>>     operator[][][][][]
>>     operator[][]
>
> But that still implies that the number of levels is to some fixed
> number, by the language requirements, but by what the author happened
> to write.

Sorry, I'm not sure how I dropped a couple of words.

What I meant to write was:

But that still implies that the number of levels is *limited* to some
fixed number, *not* by the language requirements, but by what the
author happened to write.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center             <*>  <http://users.sdsc.edu/~kst>
We must do something.  This is something.  Therefore, we must do this.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: spam@spamguard.com ("Gene Bushuyev")
Date: Fri, 28 Jul 2006 05:22:37 GMT
Raw View
""Andrei Alexandrescu (See Website For Email)"" <SeeWebsiteForEmail@erdani.org>
wrote in message news:44C91495.4070707@erdani.org...
> Gene Bushuyev wrote:
>> "Frederick Gotham" <fgothamNO@SPAM.com> wrote in message
[...]
>> It's not messy, it reflects the organization of subscript-able classes (e.g.
>> matrix). Even if there were multiple [] operators, one's matrix library would
>> be incomplete without ways of defining classes for rows and columns, which in
>> turn must define operator[]. So the multiple [] operator wouldn't be used
>> anyway. There probably isn't a mathematical model of anything that would have
>> a need for multiple [] only and not also a need for single operator [].
>
> I agree with Frederick; it's messy. I remember having read an article on
> implementing this technique. In spite of the author's valiant efforts, the
> compiler was unable to see through and generate efficient code for the
> multiple subscript. The net result was four times slower than the not-so-sexy
> alternative, which puts the technique straight in the useless bin -
> particularly since we're talking about matrix operations.

Creating proxies for rows and columns is necessary for completely independent
reasons. Every general purpose matrix library has to do that. If performance is
an issue, a not-so-sexy alternative of using a named function or operator(),
which is free from all those problems, is readily available. So why create an
operator[][][][] monstrosity for non-existing problem?

--
Gene Bushuyev (www.gbresearch.com)
----------------------------------------------------------------
To see what is in front of one's nose needs a constant struggle ~ George Orwell

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: SeeWebsiteForEmail@erdani.org ("Andrei Alexandrescu (See Website For Email)")
Date: Fri, 28 Jul 2006 05:24:01 GMT
Raw View
Frederick Gotham wrote:
>>The "fishing rod" solution would allow defining operator[] with any
>>statically-known number of levels.
>
>
> I shudder to think that you gathered I was implying that only:
>
>      operator[][][]
>
> should be allowed, rather than any amount of them:
>
>     operator[][][][]
>     operator[][][]
>     operator[][][][][]
>     operator[][]

I shudder to think that I was so misunderstood. :o) My point was to come
up with a way to define an operator[] that, given N, takes N arguments;
not a way to write by hand any sequence of []s.

Andrei

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: spam@spamguard.com ("Gene Bushuyev")
Date: Fri, 28 Jul 2006 06:03:51 GMT
Raw View
"Frederick Gotham" <fgothamNO@SPAM.com> wrote in message
news:Cs8yg.11934$j7.320466@news.indigo.ie...
> "Gene Bushuyev" posted:
>
>> It's not messy, it reflects the organization of subscript-able classes
>> (e.g. matrix). Even if there were multiple [] operators, one's matrix
>> library would be incomplete without ways of defining classes for rows
>> and columns, which in turn must define operator[].
>
>
> Then go ahead and define operator[] for "row" and "column" -- the definition
> of an operator[][] in "matrix" isn't stopping you from doing that.
>


Three objections,

1) ambiguity, is matrix[r][c] calling Matrix::operator[][] or Row::operator[]
because you also have "Row Matrix::operator[]" (or even built-in operator[] if
pointers returned)? Either ambiguity resolution should always pick operator[][]
or it wouldn't be ever possible to call. The ambiguity resolution that
programmer does in his mind and that compiler does may disagree.

2) two (many) ways of doing the same thing. Matrix::operator[][] should return
the same thing as Row::operator[] or it becomes a recipe for pervasive errors.
Programmer have to care about consistency.

3) solution of using a named function or operator() is free from all those
problems, so why complicate life?

--
Gene Bushuyev (www.gbresearch.com)
----------------------------------------------------------------
To see what is in front of one's nose needs a constant struggle ~ George Orwell

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: musiphil@bawi.org (Seungbeom Kim)
Date: Fri, 28 Jul 2006 13:38:40 GMT
Raw View
Gene Bushuyev wrote:
>
> Three objections,
>
> 1) ambiguity, is matrix[r][c] calling Matrix::operator[][] or Row::operator[]
> because you also have "Row Matrix::operator[]" (or even built-in operator[] if
> pointers returned)? Either ambiguity resolution should always pick operator[][]
> or it wouldn't be ever possible to call. The ambiguity resolution that
> programmer does in his mind and that compiler does may disagree.
>
> 2) two (many) ways of doing the same thing. Matrix::operator[][] should return
> the same thing as Row::operator[] or it becomes a recipe for pervasive errors.
> Programmer have to care about consistency.

True, these are valid points. For the sake of consistency, allowing many
ways of doing the same thing is best avoided.

> 3) solution of using a named function or operator() is free from all those
> problems, so why complicate life?

Again, for consistency: built-in multi-dimensional arrays use a[i][j][k]
notation, so it is desirable to be able to use the same syntax for user-
defined types as well.

And for the same reason as that of operator overloading: operators
provide more natural and more intuitive ways to represent the concept.
Just as x.multiply(y.add(z)) is possible but not as good as x * (y + z),
a.at(i, j, k) or a.at(i).at(j).at(k) is possible but not as good as
a[i][j][k] (or a[i, j, k], which is more debatable).

--
Seungbeom Kim

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Fri, 28 Jul 2006 13:39:09 GMT
Raw View
> My point was to come up with a way to define an operator[] that, given
> N, takes N arguments; not a way to write by hand any sequence of []s.


I'm not quite sure I understand, but do you mean something like:


    int &operator[3](unsigned,unsigned,unsigned);

    SomeType &operator[2](unsignd,unsigned);


whereby we can specify the amount of arguments.

--

Frederick Gotham

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Fri, 28 Jul 2006 15:02:49 GMT
Raw View
"Gene Bushuyev" posted:

> Creating proxies for rows and columns is necessary for completely
> independent reasons. Every general purpose matrix library has to do
> that. If performance is an issue, a not-so-sexy alternative of using a
> named function or operator(), which is free from all those problems, is
> readily available. So why create an operator[][][][] monstrosity for
> non-existing problem?


Inefficiency is a problem. Unnecessarily messy and complicated code is a
problem.

Who wants to define bastard intermediate classes to accomplish a task in a
messy and inefficient way, when they could simply define:

    int &operator[][][];

or perhaps:

    int &operator[3];

    int &operator[]<3>;

--

Frederick Gotham

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Fri, 28 Jul 2006 15:02:26 GMT
Raw View
Gene Bushuyev posted:

> Three objections,
>
> 1) ambiguity, is matrix[r][c] calling Matrix::operator[][] or
> Row::operator[] because you also have "Row Matrix::operator[]" (or even
> built-in operator[] if pointers returned)? Either ambiguity resolution
> should always pick operator[][] or it wouldn't be ever possible to call.


Indeed, as I specified elsethread: When the compiler sees:

    matrix[r][c]

, it should:

    (1) Look for Matrix::operator[][]

    (2) Failing that, look for Matrix::operator[]


> 2) two (many) ways of doing the same thing. Matrix::operator[][] should
> return the same thing as Row::operator[] or it becomes a recipe for
> pervasive errors.


This could be achieved quite easily:

    int &Matrix::operator[][](...

    Row Matrix::operator[](...

    int &Row::operator[](...


> 3) solution of using a named function or operator() is free from all
> those problems, so why complicate life?


For array syntactic sugar which works efficiently.

--

Frederick Gotham

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: v.Abazarov@comAcast.net ("Victor Bazarov")
Date: Fri, 28 Jul 2006 15:04:23 GMT
Raw View
Frederick Gotham wrote:
>> My point was to come up with a way to define an operator[] that,
>> given N, takes N arguments; not a way to write by hand any sequence
>> of []s.
>
>
> I'm not quite sure I understand, but do you mean something like:
>
>
>    int &operator[3](unsigned,unsigned,unsigned);
>
>    SomeType &operator[2](unsignd,unsigned);
>
>
> whereby we can specify the amount of arguments.

The number between the brackets would be superfluous.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Bo Persson" <bop@gmb.dk>
Date: Fri, 28 Jul 2006 11:09:58 CST
Raw View
"Frederick Gotham" <fgothamNO@SPAM.com> skrev i meddelandet
news:fOmyg.11947$j7.320330@news.indigo.ie...
> Gene Bushuyev posted:
>
>> Three objections,
>>
>> 1) ambiguity, is matrix[r][c] calling Matrix::operator[][] or
>> Row::operator[] because you also have "Row Matrix::operator[]" (or
>> even
>> built-in operator[] if pointers returned)? Either ambiguity
>> resolution
>> should always pick operator[][] or it wouldn't be ever possible to
>> call.
>
>
> Indeed, as I specified elsethread: When the compiler sees:
>
>    matrix[r][c]
>
> , it should:
>
>    (1) Look for Matrix::operator[][]
>
>    (2) Failing that, look for Matrix::operator[]

And what should it do when it sees cube[x][y][z] in the absense of
operator [][][] ? Is it [][] and [], or [] and [][] ?

What about hyper[x][y][z][w]  ?

Is it [][][] and [], or [][] and [][]?


>
>
>> 2) two (many) ways of doing the same thing. Matrix::operator[][]
>> should
>> return the same thing as Row::operator[] or it becomes a recipe for
>> pervasive errors.
>
>
> This could be achieved quite easily:
>
>    int &Matrix::operator[][](...
>
>    Row Matrix::operator[](...
>
>    int &Row::operator[](...

So now you have to define three operators instead of two. Improvement?
:-)


>
>
>> 3) solution of using a named function or operator() is free from
>> all
>> those problems, so why complicate life?
>
>
> For array syntactic sugar which works efficiently.

Is this idea limited to operator[], [][], [][][], or could i define
anyone I like?

operator>
operator>>
operator>>>
operator>>>>

operator+++
operator+*

?


Bo Persson


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Fri, 28 Jul 2006 11:26:35 CST
Raw View
Frederick Gotham wrote:
> Operators are independant of each other. They're processed individually. If
> you use one particular operator in an expression, it doesn't alter the
> effect of any other operator which is present in the expression. I believe,
> however, that one exception was made -- where the addressof and dereference
> operators appear together. I'm not sure if it was the C committee or the
> C++ committee, but one of them decided that the following should be
> perfectly legal:
>
>     int array[5];
>
>     int *p = &array[5];
>
> Obviously, this becomes:
>
>     int *p = &( *(array + 5) );
>
> As you can see, the "pointer to one past last" is dereferenced, so this
> *should* invoke UB. But, because it has the addressof operator right behind
> it, the committee decided that they should cancel each other out to yield
> perfectly valid code.
>
Did you ever programmed a compiler? I guess that the answer is no...
Otherwise you'll be perfectly aware that "dereferencing" a pointer has
no UB, and that doesn't require any "magic". Even a dumb B interpreter
written in the stone age behaves correctly for that.

This statement (full-expression statement)

*(array+5);

Is well defined too.

Why? Because it is an lvalue, and no lvalue-to-rvalue conversion (see
[conv.lval]) takes place.
What has UB with lvalues pointing to an invalid thing, is to:

Assign it with an assignment operator or an increment/decrement
operator (=, +=, -=, ++, -- etc.)
Or convert it to an rvalue through an lvalue-to-rvalue conversion.

That happens quite easily, since many operators (like +, -, /, unary
and binary *) expect an rvalue as operand.

> So that's an example of one operator altering the affect of another
> operator, and of how operators don't have to be independant of each other
> in an expression.
>
Wrong.

> Perhaps this should be done again -- where multiple pairs of square
> brackets appear together. They should be given special treatment, such that
> we can write an operator overload such as the following:
>
Even if I didn't agree with the first part of your post, I agree with
the fact that your proposal is not meaningless.
Now, the question is : Does it worth it, knowing that it can be
emulated through proxy?
And the big advantage with proxy is that intermediate objects really
exist and can be passed to functions...

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Frederick Gotham <fgothamNO@SPAM.com>
Date: Fri, 28 Jul 2006 11:49:10 CST
Raw View
Bo Persson posted:

> And what should it do when it sees cube[x][y][z] in the absense of
> operator [][][] ? Is it [][] and [], or [] and [][] ?

[][] and then [].

If you would like the latter form, use parentheses:

    (cube[x])[y][z]

I explained elsethread that the compiler should pick the largest one it can
find -- if it can't find operator[][][][], then look for operator[][][],
then look for operator[][], then look for operator[].


> What about hyper[x][y][z][w]  ?
>
> Is it [][][] and [], or [][] and [][]?


[][][] and []


>>> 2) two (many) ways of doing the same thing. Matrix::operator[][]
>>> should
>>> return the same thing as Row::operator[] or it becomes a recipe for
>>> pervasive errors.
>>
>>
>> This could be achieved quite easily:
>>
>>    int &Matrix::operator[][](...
>>
>>    Row Matrix::operator[](...
>>
>>    int &Row::operator[](...
>
> So now you have to define three operators instead of two. Improvement?
>:-)


I only did that because someone mentioned that they NEED to have a "Row"
class, and that a Row object must be retrievable from "Matrix::operator[]".

In such a case, one could still provide Matrix::operator[][] for
efficiency's sake.


>>> 3) solution of using a named function or operator() is free from
>>> all
>>> those problems, so why complicate life?
>>
>>
>> For array syntactic sugar which works efficiently.
>
> Is this idea limited to operator[], [][], [][][], or could i define
> anyone I like?
>
> operator>
> operator>>
> operator>>>
> operator>>>>
>
> operator+++
> operator+*
>
> ?


We're only talking about operator[].

Or do I detect sarcasm?

--

Frederick Gotham

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Bo Persson" <bop@gmb.dk>
Date: Fri, 28 Jul 2006 14:08:45 CST
Raw View
"Frederick Gotham" <fgothamNO@SPAM.com> skrev i meddelandet
news:sPqyg.11960$j7.320557@news.indigo.ie...
> Bo Persson posted:
>
>>>> 2) two (many) ways of doing the same thing. Matrix::operator[][]
>>>> should
>>>> return the same thing as Row::operator[] or it becomes a recipe
>>>> for
>>>> pervasive errors.
>>>
>>>
>>> This could be achieved quite easily:
>>>
>>>    int &Matrix::operator[][](...
>>>
>>>    Row Matrix::operator[](...
>>>
>>>    int &Row::operator[](...
>>
>> So now you have to define three operators instead of two.
>> Improvement?
>>:-)
>
>
> I only did that because someone mentioned that they NEED to have a
> "Row"
> class, and that a Row object must be retrievable from
> "Matrix::operator[]".
>
> In such a case, one could still provide Matrix::operator[][] for
> efficiency's sake.

My point was perhaps that supporting this adds to the requirements for
the compiler implementors. It is much better if they spend their
effort on the optimizer, as some has already done. How can we be sure
that the compiler that cannot chain two operator[] properly, will do
better for an operator[][] ? And why should compilers that already
work add an operator they don't need?

As I said elsewhere, should we change the language to support the bad
compilers, or should we demand good ones?


>>>> 3) solution of using a named function or operator() is free from
>>>> all
>>>> those problems, so why complicate life?
>>>
>>>
>>> For array syntactic sugar which works efficiently.
>>
>> Is this idea limited to operator[], [][], [][][], or could i define
>> anyone I like?
>>
>> operator>
>> operator>>
>> operator>>>
>> operator>>>>
>>
>> operator+++
>> operator+*
>>
>> ?
>
>
> We're only talking about operator[].

Yes, but why?  :-)

>
> Or do I detect sarcasm?

Some.


Bo Persson


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Wed, 26 Jul 2006 16:20:30 GMT
Raw View
kanze posted:

> On the other hand, both C and C++ already have a syntax
> for indexing "multiple dimension arrays": [i][j][k].  If at all
> possible, a solution should be found which preserves this
> notation.


(I still haven't quite formulated this in my mind yet, so I might have a
little difficulty in wording this...)

Operators are independant of each other. They're processed individually. If
you use one particular operator in an expression, it doesn't alter the
effect of any other operator which is present in the expression. I believe,
however, that one exception was made -- where the addressof and dereference
operators appear together. I'm not sure if it was the C committee or the
C++ committee, but one of them decided that the following should be
perfectly legal:

    int array[5];

    int *p = &array[5];

Obviously, this becomes:

    int *p = &( *(array + 5) );

As you can see, the "pointer to one past last" is dereferenced, so this
*should* invoke UB. But, because it has the addressof operator right behind
it, the committee decided that they should cancel each other out to yield
perfectly valid code.

So that's an example of one operator altering the affect of another
operator, and of how operators don't have to be independant of each other
in an expression.

Perhaps this should be done again -- where multiple pairs of square
brackets appear together. They should be given special treatment, such that
we can write an operator overload such as the following:

class MyClass {
protected:
    int array[5][6][7];

public:
    int &operator[][][](unsigned const a,unsigned const b,unsigned const c)
    {
        return array[a][b][c];
    }
};


When the compiler sees an expression of the type:

    obj[1][2][3] = 5;


It should:

    (1) Look for an operator[][][]

If that fails, it should:

    (2) Look for an operator[][]

If that fails, it should:

    (3) Look for an operator[]

It should keep scaling downwards until it finds a match. That way, no
existing code would be broken.

Probably the best idea I've had all year. : )

--

Frederick Gotham

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: johnchx2@yahoo.com
Date: Wed, 26 Jul 2006 14:20:16 CST
Raw View
Frederick Gotham wrote:

>  I'm not sure if it was the C committee or the
> C++ committee, but one of them decided that the following should be
> perfectly legal:
>
>     int array[5];
>
>     int *p = &array[5];
>
> Obviously, this becomes:
>
>     int *p = &( *(array + 5) );
>
> As you can see, the "pointer to one past last" is dereferenced, so this
> *should* invoke UB. But, because it has the addressof operator right behind
> it, the committee decided that they should cancel each other out to yield
> perfectly valid code.

IIRC, that's true in C99, but not in C++.  The committee is approaching
it differently in C++ (partly becuase operator overloading makes
treating particular combinations of operators as special cases a less
good idea).

  http://www2.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: cbarron413@adelphia.net (Carl Barron)
Date: Thu, 27 Jul 2006 14:52:46 GMT
Raw View
In article <9wMxg.11890$j7.320282@news.indigo.ie>, Frederick Gotham
<fgothamNO@SPAM.com> wrote:

> kanze posted:
>
> > On the other hand, both C and C++ already have a syntax
> > for indexing "multiple dimension arrays": [i][j][k].  If at all
> > possible, a solution should be found which preserves this
> > notation.
>
>
> (I still haven't quite formulated this in my mind yet, so I might have a
> little difficulty in wording this...)

template <class T,size_t cols,size_t rows>
class Matrix
{
   T  data[rows*cols];
public:
   struct subscript_proxy
   {
      T  *data;
      int i;
      subscript_proxy(T *a,int b):data(a),i(b){}
      T & operator [] (int j) {return data[i+j];}
   };
   subscript_proxy operator [] (int i)
   {
      return subscript_proxy(data,i*cols);
   }
};
or build an array of T*s in the ctor

template<class T,size_t rows,size_t cols>
class Matrix
{
   T  data[rows*cols];
   T *row_start[rows];
{
   Matrix()
   {
      T *p = data;
      for(int i=0;i!=rows;++i,p+=cols)
         row_start[i] = p;
   }
   T * operator [] (int i) {return row_start[i];}
};

now  Matrix A;
      x = A[i][j]   first calls Matrix::operator [](i) and then the
operator [](j) [either the built in for double * , or
subscript_proxy::operator [] depending on which of above
implementations is used ]

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]