Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C和x2B之间浇铸+;具有相同参数和兼容返回值的方法指针_C++_Reinterpret Cast - Fatal编程技术网

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
    的使用变得可疑。尽管如此,如果有问题,我还是不知道它来自哪里和调用as
    dispatch(g,1)
    std::function
    似乎在这方面效果不错!
    Gen g;
    A* b = dispatch(g, 1);