Topic: Iterators and operator->*()


Author: dwalker07@snet.net.invalid (Daryle Walker)
Date: 2000/08/14
Raw View
Scott Meyers <smeyers@aristeia.com> wrote:

> On Mon,  7 Aug 2000 16:51:05 GMT, Daryle Walker wrote:
> >     template <typename U>
> >     U operator->*( U T::* mp ) const { return operator->()->*mp; }
> >
> > If U gives a data member-pointer, I should be able to get that piece of
> > data from a class and use it for whatever I want.  The same thing should
> > happen if U gives a function member-pointer, including the ability to
> > apply operator() to it to call the method.
>
> It won't work for ptrs to member functions, because you haven't specified a
> parameter list.
>
> I attacked this problem last year in a DDJ article.  You can read it at
> http://www.ddj.com/articles/1999/9910/9910b/9910b.htm

In that article, you said:

//======================================================================
There are at least two problems with your approach:

1.  You can't use pointers to data members (though this is easy enough
to solve).

2.  You can't use user-defined pointers-to-members. If someone has
overloaded operator->* to take objects that act like member pointers,
you may want to support such "smart pointers to members" in your smart
pointer class. Unfortunately, you need traits classes to get the result
type of such overloaded operator->*s.

Smart pointers to members! Yikes! Esa's right. (Actually, he's more
right than I originally realized. Shortly after writing the draft of
this article, one of my consulting clients showed me a problem that was
naturally solved by smart pointers to members. I was surprised, too.)
Fortunately, this article is long enough that I can stop here and leave
ways of addressing Esa's observations in the time-honored form of
exercises for the reader. So I will.
//======================================================================

I guess I'm on the verge of solving problem [1], but are there any
examples of [2]?

On a seperate note, how can we support pointer to member functions with
arbitrary arguments (in type and amount)?  Would we have to generalize
the va_* mechanism to a full-blown new C++ concept (like objects, types,
templates, and namespaces)?  This mechanism would have to allow the
copying of a parameter list, or part of one, to another function without
having to specifiy each parameter.

--
Daryle Walker
Mac, Internet, and Video Game Junkie
dwalker07 AT snet DOT net

---
[ 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: llewelly.@@edevnull.dot.com
Date: 2000/08/15
Raw View
dwalker07@snet.net.invalid (Daryle Walker) writes:

[snip]
> On a seperate note, how can we support pointer to member functions with
> arbitrary arguments (in type and amount)?  Would we have to generalize
> the va_* mechanism to a full-blown new C++ concept (like objects, types,
> templates, and namespaces)?  This mechanism would have to allow the
> copying of a parameter list, or part of one, to another function without
> having to specifiy each parameter.

I think there are many other situations (for example, typesafe callbacks) that
  would benefit greatly from a typesafe variable argument extension.



However, for the specific case of operator->*(), there could have been a
  simpler answer: treat operator->()* the same as operaor->() . That is,
  apply ->* to the return value of operator->*() .

---
[ 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: 2000/08/13
Raw View
On Mon,  7 Aug 2000 16:51:05 GMT, Daryle Walker wrote:
>     template <typename U>
>     U operator->*( U T::* mp ) const { return operator->()->*mp; }
>
> If U gives a data member-pointer, I should be able to get that piece of
> data from a class and use it for whatever I want.  The same thing should
> happen if U gives a function member-pointer, including the ability to
> apply operator() to it to call the method.

It won't work for ptrs to member functions, because you haven't specified a
parameter list.

I attacked this problem last year in a DDJ article.  You can read it at
http://www.ddj.com/articles/1999/9910/9910b/9910b.htm

Scott

---
[ 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: dwalker07@snet.net.invalid (Daryle Walker)
Date: 2000/08/07
Raw View
<llewellyat@dbritschdot.dsldot.xmissiondot.com> wrote:

> dwalker07@snet.net.invalid (Daryle Walker) writes:
>
> > I know that iterator classes generally have an operator->().  Why don't
> > they have an operator->*()?  Conceptually, any type that can use the
> > first one can also use the second (regular pointers can do this).

> The rhs of operator->*() can be a pointer to a member function.

[SNIP a demostration that each type of various member function signature
that could be on the RHS would have to be planned for individually by
overloading ->*, making it hard to generalize.]

You forgot to mention pointers to member variables (of any type).  -_^

But isn't this a solution:

//======================================================================
// WARNING: not compiled (but tested code kind-of like this)
#include <cassert>

template <typename T>
class my_smart_ptr
{
    //...

    T* get() const { return blah_blah; }

    T* operator->() const { T *t = get(); assert(t); return t; }

    T& operator*() const { return *operator->(); }

    template <typename U>
    U operator->*( U T::* mp ) const { return operator->()->*mp; }

    //...
};
//======================================================================

If U gives a data member-pointer, I should be able to get that piece of
data from a class and use it for whatever I want.  The same thing should
happen if U gives a function member-pointer, including the ability to
apply operator() to it to call the method.  Using templates, it does not
matter what the method's signature is, or how many (data and function)
members the class has (including inhierited ones)!

I wrote code like this, and it worked for data member pointers.  I
haven't tried out a function member pointer yet.  I hope it works.  If
it doesn't, the next C++ standard should be changed to allow it.

--
Daryle Walker
Mac, Internet, and Video Game Junkie
dwalker07 AT snet DOT net

---
[ 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: dwalker07@snet.net.invalid (Daryle Walker)
Date: 2000/08/01
Raw View
I know that iterator classes generally have an operator->().  Why don't
they have an operator->*()?  Conceptually, any type that can use the
first one can also use the second (regular pointers can do this).

--
Daryle Walker
Mac, Internet, and Video Game Junkie
dwalker07 AT snet DOT net

---
[ 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: llewellyat@dbritschdot.dsldot.xmissiondot.com
Date: 2000/08/01
Raw View
dwalker07@snet.net.invalid (Daryle Walker) writes:

> I know that iterator classes generally have an operator->().  Why don't
> they have an operator->*()?  Conceptually, any type that can use the
> first one can also use the second (regular pointers can do this).
>
[snip]

The rhs of operator->*() can be a pointer to a member function.

For iterator types, this ends up being something like:

  Return_type (T::*T_method_0)()

  or:

  Return_type (T::*T_method_1)(Arg_1_type)

  or:

  Return_type (T::*T_method_2)(Arg_1_type,Arg_2_type)

I think you can see where this is going. The problem is that C++ has
  no mechanism for dealing with argument lists of unknown length.

  ... is not even remotely typesafe, making it useless (or worse) for
    most C++ code.

  overloading only allows one to select amoung a finite set (almost
    always small) of known lengths.

  the <iostream> approach requires a change in the function call
    syntax.

---
[ 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              ]