Topic: conversion to base pointer


Author: "Greg Brewer" <nospam.greg@brewer.net>
Date: Fri, 28 Jun 2002 19:04:46 GMT
Raw View
"Pete Becker" <petebecker@acm.org> wrote in message
news:3D17B610.3E396B2B@acm.org...
> Greg Brewer wrote:
> > Why can't it?  Is it a compiler problem?  Why can't it do the conversion
if
> > the implementation of F1 is okay?
> Let's simplify it:
> class Base
> {
> publci:
> int j;
> };
> class Derived : public Base
> {
> public:
> int i;
> };
> int Derived::*dp = &Derived::i;
> int Base::*bp = dp; // illegal
> There is no 'i' in Base, so if it were legal, bp would point off into
> the weeds. The implicit conversion goes the other way:
> int Base::*bp = &Base::j;
> int Derived::*dp = bp; // okay, every Derived has a 'j'

My example went more like

int Derived::*dp = &Derived::j;
int Base::*bp = dp; // illegal

but your point is well taken; there is a lack of a guarentee.
void Set(Base::*bp, Base *b) {b->*bp = 5;}
works correctly only if b was created from Derived.  If
b was in fact created from Derived2 where i is a float then the
value 5 will likely be written into the space for a float.

But it does not adequately describe my problem.  What I am doing
is more like
int Derived::*dp = &Derived::j;
and in fact works fine for instances where j is int, short, long, and float.
Where I run into problems is when the type is derived.

class Int1
{
public:
   int v;
};
class Int2 : public Int1
{
public:
   int u;
};
 class Base
{
publci:
Int2 j;
};
class Derived : public Base
{
public:
int i;
};
In this case, I would expect
Int2 Derived::*dp = &Derived::j;
to work fine (and it may, I haven't tested it).  But
what does not work is
Int1 Derived::*dp = &Derived::j;
so that I cannot do
void Set(Drived::*dp, Derived*d) {(d->*bp).v = 5;}
which I would expect to be perfectly safe.

Greg



---
[ 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: "Greg Brewer" <nospam.greg@brewer.net>
Date: Fri, 21 Jun 2002 22:03:28 GMT
Raw View
I have the following defined as a basic data class
class EN_Base
      {
      public:
         char v;
      };
      template <int i>
      class EN : public EN_Base
      {
      public:
      };

and then I have a class that uses this basic data class
      class TR
      {
      public:
         enum {YN=-1, XX=501};
         EN<YN> yn;
         EN<XX> xx;
      };

Now, I would like to have a single function to act on the data members such
as
      void F1(TR& tr, EN_Base TR::*v) { (tr.*v).v = 'x';}
so that it can be called like
      void Fn1(void)
      {
         TR tr;
         F1(tr, &TR::yn);
      }
but the compiler says it can't convert 'EN<-1> TR::*' to 'EN_Base TR::*'.

Why can't it?  Is it a compiler problem?  Why can't it do the conversion if
the implementation of F1 is okay?

Greg Brewer





---
[ 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: "Giovanni Bajo" <giovannibajo@REMOVEliberoTHIS.it>
Date: 24 Jun 2002 02:30:11 GMT
Raw View
"Greg Brewer" <nospam.greg@brewer.net> ha scritto nel messaggio
news:af078i$2q8o$1@news.hal-pc.org...

> Why can't it?  Is it a compiler problem?  Why can't it do the conversion
if
> the implementation of F1 is okay?

Probably it's ok to convert a pointer, but not a data member pointer (and
even an explcit static_cast<> produces the same error). Wait for some
standard expert on this. Of course, the case you brought can be fixed with
an easy:

template <int A>
void F1(TR& tr, EN<A> TR::*v) { (tr.*v).v = 'x';}

But this is probably not what you were looking for.

Giovanni Bajo

---
[ 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: Pete Becker <petebecker@acm.org>
Date: Tue, 25 Jun 2002 06:53:43 GMT
Raw View
Greg Brewer wrote:
>
> Why can't it?  Is it a compiler problem?  Why can't it do the conversion if
> the implementation of F1 is okay?

Let's simplify it:

class Base
{
publci:
 int j;
};

class Derived : public Base
{
public:
 int i;
};

int Derived::*dp = &Derived::i;
int Base::*bp = dp; // illegal

There is no 'i' in Base, so if it were legal, bp would point off into
the weeds. The implicit conversion goes the other way:

int Base::*bp = &Base::j;
int Derived::*dp = bp; // okay, every Derived has a 'j'

You can do the original conversion with a cast, but before you use the
resulting pointer yo must cast it back to it's original type:

int Derived::*dp = &Derived::i;
int Base::*bp = (int Base::*)dp;
Base b;
b.*bp; // undefined
Derived d;
d.*(int Derived::*)bp; // okay

--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]