简体   繁体   中英

Is it safe to cast a member function pointer to one of another class and back again?

Reading the answer to this question ( Casting a function pointer to another type ), I understand that it is safe to cast pointers like void(*)(A*) to pointers like void(*)(B*) , you just need to cast them back before calling them.

Does this also work for member function pointers? Can I safely cast void(A::*)() to void(B::*)() and cast it back before calling it?

Example code that seems to work at least on my system:

#include <iostream>

struct A {
  void f() { std::cout << "called" << std::endl; }
};

struct B {};

int main() {
  A instance;
  auto ptr = reinterpret_cast<void (B::*)()>(&A::f);
  (instance.*(reinterpret_cast<void (A::*)()>(ptr)))();
}

I believe, yes. Here is what I find in standard (5.2.10):

A prvalue of type “pointer to member of X of type T1” can be explicitly converted to a prvalue of a different type “pointer to member of Y of type T2” if T1 and T2 are both function types or both object types. The null member pointer value (4.11) is converted to the null member pointer value of the destination type. The result of this conversion is unspecified, except in the following cases:

— converting a prvalue of type “pointer to member function” to a different pointer to member function type and back to its original type yields the original pointer to member value.

— converting a prvalue of type “pointer to data member of X of type T1” to the type “pointer to data member of Y of type T2” (where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer to member value.

From 5.2.10/10 ( reinterpret_cast ) we learn:

A prvalue of type “pointer to member of X of type T1” can be explicitly converted to a prvalue of a different type “pointer to member of Y of type T2” if T1 and T2 are both function types or both object types.71 The null member pointer value (4.11) is converted to the null member pointer value of the destination type. The result of this conversion is unspecified, except in the following cases:

  • converting a prvalue of type “pointer to member function” to a different pointer to member function type and back to its original type yields the original pointer to member value.

In this case you're casting to and from pointer-to-member-function (both point to functions), so it looks like it's totally legal.

5.4 [expr.cast] says that you can use reinterpret_cast to convert a pointer-to-member-of-derived to a pointer-to-member-of-base and back. Of course, you have to convert back to the derived type in order to use the pointer, since there is no guarantee that the function it points to is actually a member of the base.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM