Topic: Fwd: pointer to member conversion to a pointer to member that
Author: v.Abazarov@comAcast.net (Victor Bazarov)
Date: Fri, 20 Aug 2004 23:27:25 GMT Raw View
Hyman Rosen wrote:
> Victor Bazarov wrote:
>
>> The basic idea is: if for two classes B and D exists an implicit
>> conversion from { D* to B* } (plain vanilla ptr-to-derived to ptr-to-base
>> conversion, see 4.10), then the conversion { D T::* to B T::* } for an
>> arbitrary class T should exist as well. I there anything I am missing?
>
>
> When the converted pointer is called, there may need to be fixup code
> generated to the D -> B conversion, so I don't think handling this is
> particularly easy. Here's example code:
>
> struct A { double a; };
> struct B { unsigned b; };
> struct AB : A, B { long ab; };
> struct X { AB ab() { return AB(); } };
>
> int main()
> {
> AB (X::*fab)() = &X::ab;
> B (X::*fb)() = fab; // The suggested conversion
> X x;
> B b = (x.*fb)();
> }
What fixup code?
I don't think that I asked for this type of conversion. I was talking
member objects, not member functions. Here is a simple[r] example of
what is needed:
struct B { virtual int foo() const = 0; };
struct D : B { virtual int foo() const { return 42; } };
struct DD : B { virtual int foo() const { return 43; } };
struct X { B X::* pb; D d; DD dd;
int dofoo() const { (this->*pb).foo(); } };
int main()
{
X x;
x.pb = &X::d; // ***
int fortytwo = x.dofoo(); // makes fortytwo == 42
x.pb = &X::dd; // ***
int fortythree = x.dofoo(); // makes fortythree == 43
}
The 'X::dofoo' function is of interest. It takes the pointer to member
of X of class B and calls the virtual function on it. What should happen
is this: whatever this pointer points to should get its final overrider
called. If I make pb point to a 'd', the D::foo should be called but for
the object 'd' in the 'x'. Same if pb points to 'dd'.
Right now it "works" if a reinterpret_cast is used on the right sides of
the assignments on lines marked with '***'. But reinterpret_cast does not
allow that type of conversion either. I submit an implicit conversion of
that sort should exist. Is there anything that would make it difficult?
Thanks.
Victor
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: v.Abazarov@comAcast.net (Victor Bazarov)
Date: Mon, 23 Aug 2004 15:55:41 GMT Raw View
Bob Hairgrove wrote:
> On Fri, 20 Aug 2004 23:27:25 GMT, v.Abazarov@comAcast.net (Victor
> Bazarov) wrote:
>
>
>>I don't think that I asked for this type of conversion. I was talking
>>member objects, not member functions. Here is a simple[r] example of
>>what is needed:
>>
>> struct B { virtual int foo() const = 0; };
>> struct D : B { virtual int foo() const { return 42; } };
>> struct DD : B { virtual int foo() const { return 43; } };
>> struct X { B X::* pb; D d; DD dd;
>> int dofoo() const { (this->*pb).foo(); } };
>>
>> int main()
>> {
>> X x;
>> x.pb = &X::d; // ***
>> int fortytwo = x.dofoo(); // makes fortytwo == 42
>> x.pb = &X::dd; // ***
>> int fortythree = x.dofoo(); // makes fortythree == 43
>> }
>>
>>The 'X::dofoo' function is of interest. It takes the pointer to member
>>of X of class B and calls the virtual function on it. What should happen
>>is this: whatever this pointer points to should get its final overrider
>>called. If I make pb point to a 'd', the D::foo should be called but for
>>the object 'd' in the 'x'. Same if pb points to 'dd'.
>>
>>Right now it "works" if a reinterpret_cast is used on the right sides of
>>the assignments on lines marked with '***'. But reinterpret_cast does not
>>allow that type of conversion either. I submit an implicit conversion of
>>that sort should exist. Is there anything that would make it difficult?
>
>
> Actually, as John Harrison pointed out to me in another thread on
> comp.lang.c++, this can also be done much more easily using normal
> pointers, i.e.:
>
> #include <iostream>
> #include <ostream>
>
> struct B { virtual int foo() const = 0; };
> struct D : B { virtual int foo() const { return 42; } };
> struct DD : B { virtual int foo() const { return 43; } };
> struct X { B * pb; D d; DD dd; // pb is now simply a B*
> int dofoo() const { return pb->foo(); } };
>
> int main()
> {
> X x;
> x.pb = &(x.d); // ***
> int fortytwo = x.dofoo(); // makes fortytwo == 42
> x.pb = &(x.dd); // ***
> int fortythree = x.dofoo(); // makes fortythree == 43
>
> std::cout << "fortytwo:\t" << fortytwo << std::endl;
> std::cout << "fortythree:\t" << fortythree << std::endl;
> return 0;
> }
Right. This works fine. Now imagine this situation:
--------------------------------
struct B { virtual int foo() const = 0; };
struct D : B { virtual int foo() const { return 42; } };
struct DD : B { virtual int foo() const { return 43; } };
struct X { static B X::* pb; D d; DD dd; // ******* pb is now static!
int dofoo() const { (this->*pb).foo(); } };
int main()
{
X x[5];
X::pb = &X::d; // ***
for (int i = 0; i < 5; ++i)
int fortytwo = x[i].dofoo(); // makes fortytwo == 42
X::pb = &X::dd; // ***
for (int i = 0; i < 5; ++i)
int fortythree = x[i].dofoo(); // makes fortythree == 43
}
--------------------------------
In this example, the 'pb' member is static. Yes, I have to admit this
example is somewhat artificial, but imagine that there is some kind of
global dispatch mechanism that should change the behaviour of _all_ X
objects at some point without knowing how many there are. It could be
done with a flag and then every object has to check the flag and do as
prescribed (which is a bit less efficient, probably).
Anyway, in this case, we cannot make 'pb' a pointer to an object, simply
because that has to be done for every instance of 'X'. What to do in
this case?
Thank you for your interest in this problem. I wish I could get a bit
more participation from other frequents here.
Victor
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]