C++ 在C和x2B之间浇铸+;具有相同参数和兼容返回值的方法指针
假设您有以下类:C++ 在C和x2B之间浇铸+;具有相同参数和兼容返回值的方法指针,c++,reinterpret-cast,C++,Reinterpret Cast,假设您有以下类: class A {}; class B : public A {}; class C : public A {}; class Gen { public: A* genA(int val); B* genB(int val); C* genC(int val); }; 有了这些,我可以做到: Gen g; A* a = g.genA(1); A* b = g.genB(1); A* c = g.genC(1); 现在,假设我想传递
class A {};
class B : public A {};
class C : public A {};
class Gen {
public:
A* genA(int val);
B* genB(int val);
C* genC(int val);
};
有了这些,我可以做到:
Gen g;
A* a = g.genA(1);
A* b = g.genB(1);
A* c = g.genC(1);
现在,假设我想传递生成函数,以避免构建枚举和表或其他间接层。(还假设因为没有编写Gen
我不能只更改返回类型。)那么我想要类似于typedef的东西:
typedef A* (Gen::*GenMethod)(int);
不幸的是,您不能直接将&Gen::genB或&Gen::genC分配给该类型的指针,也不能使用static\u cast
将其强制转换为该类型
但是,您可以使用重新解释cast
,这并不奇怪,因为重新解释cast
可以让您做各种事情
在我的测试中,对于这种情况,使用reinterpret\u cast
可以很好地测试代码。因此,我的问题是:
reinterpret\u cast
的罕见案例之一您可以将这些协变成员函数指针存储在
std::function
中:
std::function<A*(Gen&, int)> dispatch(&Gen::genB);
这是因为存储在
std::function
中的可调用函数的返回类型只需要转换为模板参数(a*
)中给定的类型,而不需要完全属于该类型。在本例中,B*
被转换为A*
我找到了一个,但找不到一个特定于您的问题的。它是UB。编译器可以假设UB永远不会发生,因此能够看穿这一技巧的编译器可以删除强制转换和周围的代码。是的,实际上不同的返回类型会带来更明显的问题。我希望static\u cast
能在这种情况下工作,而且它不会使reinterpret\u cast
的使用变得可疑。尽管如此,如果有问题,我还是不知道它来自哪里和调用asdispatch(g,1)
std::function
似乎在这方面效果不错!
Gen g;
A* b = dispatch(g, 1);