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.
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With