You have the variance backward.
Return types convert implicitly to base types (contravariance). But parameters convert implicitly to derived types (covariance), and the class type in a pointer-to-member acts as a parameter. To see this, let's apply the Liskov Substitutability Principle:
The contract of Base*
is: "I will give you a Base" (when you use the *
operator on me).
The contract of Derived*
is "I will give you a Derived, which is also a Base".
Clearly a Derived*
can be used in place of a Base*
. Therefore there is an implicit conversion from Derived*
to Base*
.
But consider the contract of a pointer-to-member.
The contract of int Base::*
is: "Give me a Base and I will give you back an int" (A Derived is a Base, so those are ok too)
The contract of int Derived::*
is: "Give me a Derived and I will give you back an int" (But not any old Base
will do, it must be a Derived
)
Imagine that you have a Base
which is not a Derived
. It will work nicely when dereferencing an int Base::*
, but cannot be used with an int Derived*
).
However, if you have a Derived
, you can use it to dereference both int Base::*
and int Derived::*
. Therefore there is an implicit conversion from int Base::*
to int Derived::*
Argh, I did what you said and analyzed the type that the member belongs to.
The LSP still works though. And I agree that the conversion should be legal, at least according to type safety. The contract is "Give me a Foo
and I will give you a Derived
", which clearly you can use to get from Foo
to Base
by composing it with an implicit conversion. So it's safe. DeadMG is probably on the right track pointing out the potential complication with the relation location of the base subobject, especially in virtual inheritance. But pointer-to-members deal with these problems on the LHS of the dereference operator, so they could for the result as well.
Final answer is probably simply that the standard doesn't require that the conversion is legal.