Question

I'm trying to use pointers to member variables in a polymorphic fashion.

This works:

struct Foo
{
   int member0;
   int member1;

   int* getMember( int i )
   {
     static int Foo::* table[2] = { &Foo::member0, &Foo::member1 };
     return &( this->*table[i] );
   }
};

This does not, since the members are not of the same type (BaseClass):

struct Foo
{
   SubClassA member0;
   SubClassB member1;

   BaseClass* getMember( int i )
   {
     static BaseClass Foo::* table[2] = { &Foo::member0, &Foo::member1 };
     return &( this->*table[i] );
   }
};

The error reported by g++ is:

[...] invalid conversion from 'SubClassA Foo::*' to 'BaseClass Foo::*'
[...] invalid conversion from 'SubClassB Foo::*' to 'BaseClass Foo::*'

Is there a way to make this work, ie to "upcast" the member pointer to its base class?

Was it helpful?

Solution

This is not possible. Because of multiple inheritance, address-of-base is not always the same as address-of-derived. You need some hidden address adjustment magic to convert one to the other, and a pointer-to-member, being a very simple object (basically an integer offset) cannot accomodate this magic.

It is true that address adjustment only needed sometimes, and when it is not needed, polymorphic pointers-to-members could in principle be allowed. But this is not done, for simplicity and consistency.

Instead of pointers-to-members, you can use pointers to functions (or function-like objects) that accept a Foo* and return a BaseClass*. You will have to make a separate function for each member though.

OTHER TIPS

BaseClass* getMember(const int i)
{
  switch(i)
  {
  case 0: return &member0;
  case 1: return &member1;
  default: throw <exception>;
  }
}

For robustness you have to anyway check if the i is within the range or 0 and 1; so you can think for this simplified approach.

The easier way to do it would be to skip the member data pointers altogether.

getMember(int i) {
    BaseClass* ptr[2] = { &member0, &member1 };
    return ptr[i];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top