将成员函数指针强制转换为另一个类并再返回一个是安全的吗?

时间:2016-03-22 15:29:45

标签: c++ pointers casting

阅读这个问题的答案(Casting a function pointer to another type),我明白将void(*)(A*)之类的指针强加到像void(*)(B*)这样的指针是安全的,你只需要在调用之前将它们强制转换回来它们。

这对成员函数指针也有效吗?我可以安全地将void(A::*)()投射到void(B::*)()并在调用之前将其投回去吗?

示例代码似乎至少在我的系统上起作用:

#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)))();
}

3 个答案:

答案 0 :(得分:3)

我相信,是的。这是我在标准(5.2.10)中找到的内容:

  

类型为“指向T1类型X的成员的指针”的prvalue可以是   显式转换为不同类型的prvalue“指向   如果T1和T2都是函数类型或两者兼有,则为T2类型Y的成员   对象类型。 null成员指针值(4.11)将转换为   目标类型的null成员指针值。的结果   除以下情况外,此转换未指定:

     

- 将“指向成员函数的指针”类型的prvalue转换为a   指向成员函数类型的不同指针并返回其原始状态   type产生指向成员值的原始指针。

     

- 将“指向类型T1的X的数据成员的指针”类型的prvalue转换为该类型   “指向类型为T2的Y的数据成员的指针”(其中对齐   T2的要求并不比T1的要求更严格并且回到它的要求   原始类型产生指向成员值的原始指针。

答案 1 :(得分:3)

从5.2.10 / 10(reinterpret_cast)我们学到:

  

类型为“指向T1类型X的成员的指针”的prvalue可以是   显式转换为不同类型的prvalue“指向   如果T1和T2都是函数类型或两者兼有,则为T2类型Y的成员   object types.71将null成员指针值(4.11)转换为   目标类型的null成员指针值。的结果   此转换未指定,但以下情况除外:

     
      
  • 将“指向成员函数的指针”类型的prvalue转换为a   指向成员函数类型的不同指针并返回其原始状态   type产生指向成员值的原始指针。
  •   

在这种情况下,你是指向成员函数的指针(都指向函数),所以它看起来完全合法。

答案 2 :(得分:-1)

5.4 [expr.cast]表示你可以使用reinterpret_cast将指向成员的指针转换为指向成员的指针并返回。当然,您必须转换回派生类型才能使用指针,因为无法保证它指向的函数实际上是基类的成员。