Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I assign a member data pointer to a derived type?

This is probably best shown with example code. The following fails to compile with g++:

struct Base {
};

struct Derived : public Base {
};

struct Container {
    Derived data_;
};

int main(void) {
    Base Container::*ptr = &Container::data_;
}

I get the following error: invalid conversion from 'Derived Container::*' to Base Container::*'. Is this not allowed by the language? Is this a compiler bug? Am I using the wrong syntax?

Please help!

Some background as to why I'm trying to do this: I have several member data pieces that I want to use primarily as their derived types, but I want to be able to populate them through some common code. Data will be coming in an arbitrary order and have a string label that I would use to select the appropriate member data to populate. I was planning on creating a std::map<std::string, Base Container::*> to assign data to each member through a common interface. I'd like to avoid have a giant if else construct to find the right member data.

like image 282
preynold Avatar asked May 16 '11 13:05

preynold


2 Answers

This is not a compiler bug, you can't do that. (But you can assign a Base::* to a Derived::*).

I don't see any good reason for the limitation (excepted that to handle the case of multiple inheritance, that would complicate even more the representation of a member pointer).

like image 197
AProgrammer Avatar answered Nov 19 '22 14:11

AProgrammer


There are a lot of fairly complex, some not-well-explained, and a few flat wrong answers in this thread.

But the problem, it seems to me, is that there simply isn't a Base member within Container -- there is a Derived member. You can't do this:

Base Container::*ptr = &Container::data_;

...for the same reason you can't do this:

int a;
long* pl = &a;

In the second example, the object isn't a long, it's an int. Similarly, in the first example the object isn't a Base, it's a Derived.

As a possibly tangential point, it seems to me like what you really want to do is have Base be an abstract class, and have Container have a Base* rather than a Derived member.

like image 1
John Dibling Avatar answered Nov 19 '22 14:11

John Dibling