To me it looks perfectly safe to cast a void(Derived::*)()
to a void(Base::*)()
, like in this code:
#include
#incl
I imagine this can be somewhat surprising. However it makes sense if you think about it.
For a cast between two types to be automatic, the following relation should hold: any instance of the first type should be representable in the second.
For example, if d
is an instance of Derived
, then it can be automatically cast as a Base&
because any instance of Derived
is also an instance of Base
. This is inheritance.
Now, when it comes to pointer to member-functions, the relation is actually reversed. It will seem obvious that any method of Base
exists for an instance of Derived
but the reverse is not true. After all the whole point of deriving is to add new functionality more often that note.
Another way of visualizing this is to use free-functions. this
is just an implicit parameter in regular function, if we make it explicit we get:
void Base@call_it(Base& self);
void Derived@a_method(Derived& self);
Now, if I have two instances d
of type Derived
and b
of type Base
then:
Base@call_it(d)
makes senseDerived@a_method(b)
is a compilation errorThe latter could be Derived@a_method(dynamic_cast
, but this introduces a runtime check to actually verify the property. Statically it is not decidable.