Topic: operator[] and read/write detection.


Author: deepblack@geocities.com (Luis Coelho)
Date: 1999/10/15
Raw View
On 11 Oct 1999 18:21:31 -0400, "Bernard Tatin"
<Bernard.Tatin@univ-orleans.fr> uttered the following words:

>If I overload operator[] how can I detect - in a standard way - if I am
>writing or reading a value ?
>
>Type& operator[](int idx)
>{
>    if (Reading())
>        // some specific code
>    else
>        // some other specific code
>    return Something;
>}
>
>My aim is to control if I am reading uninitialized elements of a vector and
>my code must be supported by different compilers and different platforms.
>
>Thanks for your answers.

Write a proxy class around your type and have it call the
functions you want for:

<code>
template <typename T>
struct Wrapper
{
 Wrapper(int index,Vector* vec)
    :index(index),
     vec(vec)
   { ; }

 T& operator = (const T&)
 { return vec->write(index); }

 operator T& ()
   { return vec->read(index); }

 private:
 int index;
 Vector* vec;
};

Type& Vector::operator[](int i)
{
 return Wrapper(i,this);
}
</code>

I leave the considerations of in what scope to put Wrapper and
etc to you.

HTH,
Luis Coelho.
C++ Programming Language, 3rd Ed. by B. Stroustrup. My exercise answers at:
http://www.geocities.com/SiliconValley/Way/3972/index.html
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/10/12
Raw View
"Bernard Tatin" <Bernard.Tatin@univ-orleans.fr> writes:
> If I overload operator[] how can I detect - in a standard way - if I am
> writing or reading a value ?
> Type& operator[](int idx)
> {
>     if (Reading())
>         // some specific code
>     else
>         // some other specific code
>     return Something;
> }

You cannot. If you really need to know this, then you must have
operator[] return a proxy class. Give this class an assignment
operator from Type, and a conversion operator to Type, and you
will then be able to handle the reading and writing cases.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/10/12
Raw View
"Bernard Tatin" <Bernard.Tatin@univ-orleans.fr> writes:

| If I overload operator[] how can I detect - in a standard way - if I am
| writing or reading a value ?

You may have to use a proxy class -- see D&E section 3.7.1 for an
illustrative example.

|
| Type& operator[](int idx)
| {
|     if (Reading())
|         // some specific code
|     else
|         // some other specific code
|     return Something;
| }
|
| My aim is to control if I am reading uninitialized elements of a vector and
| my code must be supported by different compilers and different platforms.

There is no portable way to know wheter an object is "properly"
initialized unless you make use of specific idiom such as Faillible<T>
classes.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: smeyers@aristeia.com (Scott Meyers)
Date: 1999/10/13
Raw View
On 11 Oct 1999 18:21:31 -0400, Bernard Tatin wrote:
> If I overload operator[] how can I detect - in a standard way - if I am
> writing or reading a value ?

The conventional (and portable) way is to have operator[] return a
proxy<Type> instead of a Type&.  You then use member functions of
proxy<Type> to detect whether the result of operator[] is being used as an
lvalue or an rvalue.

You can find lots of details in Item 30 of my "More Effective C++", which
is devoted to the ins and outs of this particular technique.  I'm sure
other books discuss it, too, but I'm not familair with which ones right off
the top of my head.

Scott

--
Scott Meyers, Ph.D.                  smeyers@aristeia.com
Software Development Consultant      http://www.aristeia.com/
Visit http://meyerscd.awl.com/ to demo the Effective C++ CD

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Daniel Parker" <dparker@no_spam.globalserve.net>
Date: 1999/10/14
Raw View
Bernard Tatin <Bernard.Tatin@univ-orleans.fr> wrote in message
news:7ts2gm$bdv@centre.univ-orleans.fr...

> If I overload operator[] how can I detect - in a standard way - if I am
> writing or reading a value ?

> Type& operator[](int idx)
> {
>     if (Reading())
>         // some specific code
>     else
>         // some other specific code
>     return Something;
> }

Use a proxy class, something like

class Vector {
public:
    Type* m_data;

    class Proxy {
        Type& m_value;

        Proxy(Type& value) : m_value(value) {
        }
        Proxy& operator=(const Type& rhs) {
            //  Writing specific code
            m_value = rhs;
            return *this;
        }
        operator Type() const {
            //  Reading specific code
            return m_value;
        }
    };

    Proxy operator[](int i) {
        return Proxy(m_data[i]);
    }
};

--
Regards,
Daniel Parker danielp@no_spam.nshima.com




      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Carlo Wood <ca231196@runaway.xs4all.nl>
Date: 1999/10/14
Raw View
Bernard Tatin wrote:
> If I overload operator[] how can I detect - in a standard way - if I am
> writing or reading a value ?
>
> Type& operator[](int idx)
> {
>     if (Reading())
>         // some specific code
>     else
>         // some other specific code
>     return Something;
> }
>
> My aim is to control if I am reading uninitialized elements of a vector and
> my code must be supported by different compilers and different platforms.
>
> Thanks for your answers.

That is not possible, but with a lot of effort you might
achieve something that does what you want.
Here is some code to get you started, you'll need to
write more Index<> operators when needed and add a special
case check for self assignment here and there (I am lazy).

#include <iostream>

template<class T>
class Index {
  T& t_;
  int index_;
public:
  Index(T& t, int idx) : t_(t), index_(idx) { }
  Index& operator=(const Index& t) { t_.write(index_, t.read()); return *this; }
  Index& operator=(const T& t) { t_.write(index_, t); return *this; }
  const T& read(void) const { return t_.read(index_); }
  int index(void) const { return index_; }
};

class A {
public:
  Index<A> operator[](int idx) { return Index<A>(*this, idx); }
  const Index<A> operator[](int idx) const { return Index<A>(*const_cast<A*>(this), idx); }
  A& operator=(const Index<A>& ai) { *this = ai.read(); return *this; }

  // Reading:
  const A& read(int idx) const {
    cout << "Reading from to A[" << idx << "]" << endl;
    return *this;       // fix this
  }

  // Writing:
  void write(int idx, const A& a) {
    cout << "Writing to A[" << idx << "]" << endl;
    // put code here
    return;
  }
};

int main(void)
{
  A a1;
  const A& a2(a1);
  a1[0] = a2;
  a1 = a2[1];
  a1 = a1[2] = a1[3];
}


Outputs:

Writing to A[0]
Reading from to A[1]
Reading from to A[3]
Writing to A[2]
Reading from to A[2]

Carlo Wood

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Bernard Tatin" <Bernard.Tatin@univ-orleans.fr>
Date: 1999/10/11
Raw View
If I overload operator[] how can I detect - in a standard way - if I am
writing or reading a value ?

Type& operator[](int idx)
{
    if (Reading())
        // some specific code
    else
        // some other specific code
    return Something;
}

My aim is to control if I am reading uninitialized elements of a vector and
my code must be supported by different compilers and different platforms.

Thanks for your answers.


Bernard Tatin
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]