将指向虚拟成员函数的指针作为普通C函数的参数传递

时间:2014-09-19 10:55:41

标签: c++

我需要你的帮助,因为我不知道如何实现以下目标(而且根本不可能):

假设我有一个类层次结构,如

class Base
{
public :
    .....
    virtual int fcn(unsigned, const double *, void *,unsigned, double)=0;
    ....
};

class Derived_1:public Base
{
public :
    .....
    int fcn(unsigned, const double *, void *,unsigned, double);
    ....
};

class Derived_2:public Base 
{
public :
    .....
    int fcn(unsigned, const double *, void *,unsigned, double);
    ....
};

我需要集成成员函数fcn,我想使用一个数值集成包(由SG Johnson,查看http://ab-initio.mit.edu/wiki/index.php/Cubature),其中包含(旁边的其他)一个例程定义为:

int h_cubature(unsigned fdim, integrand f, etc ..);

其中f表示要集成的函数的指针," integrand"是typedef:

typedef int (*integrand) (unsigned, const double *, void *,unsigned, double);

我试图做的是将h_cubature指向成员函数fcn的指针传递给我,我希望将其集成(此外,通过多态机制,即给定Base类类型的指针)也就是说,< / p>

int main()
    {
    Base* b;
    Derived_1 d1;
    b=&d1;
    hcubature(2, b->fcn, ........);  //<---I don't know how to pass b->fcn
    ....

如上所述将b-&gt; fcn传递给h_cubature会导致GNU GCC编译器发出错误

cannot convert 'Base::fcn' from type 'int (Base::)(unsigned int, const double *, void*, unsigned int, double*)' to type 'integrand {aka int (*)(unsigned int,const double*, void*, unsigned int, double*)}'|

无论我尝试了什么,都失败了。我看到的问题是,即使integrand和fcn都具有相同的签名和相同的返回类型,b-&gt; fcn是虚拟成员函数,而integrand是C类普通函数。

有人可以告诉我如何将b-&gt; fcn指针传递给h_cubature(或者可能告诉我这是不可能的)?

提前谢谢!

3 个答案:

答案 0 :(得分:3)

您无法将C ++(非静态)成员函数传递给C函数指针(直观地说,因为这些成员函数将this作为隐式形式论证)。

但可能,integrand的第三个形式可以是任意指针。因此,通过对象的地址,并使用integrand一些粘合extern "C"static函数:

static int my_integrand (unsigned i, const double *t, void *data, 
                         unsigned j, double x)
{
   Base* b = static_cast<Base*>data;
   assert (b != nullptr);
   return b->fcn(i,t,data,j,x);
}

我想您不需要将data传递给b->fcn(因此您可以在BaseDerived1,{{1}中更正其签名类})

稍后使用Derived2 ......

答案 1 :(得分:0)

您正在尝试将指向类成员函数的指针作为参数传递,期望指向函数的指针。这是不兼容的。

答案 2 :(得分:0)

您不能将其作为常规C函数传递,也不能使用lambda或bind。

如果您控制了该函数的void *参数,即它是一个&#34;魔术cookie&#34;你提供的,你可以使用它来实际包含一个Base *指针然后投射它并从中调用你的虚函数。

class Base
{
  public:
    virtual int fcn(unsigned, const double *,unsigned, double)=0; // no void * param
};

int BaseFcn( unsigned u1, const double * pd, void * pv unsigned u2, double d )
{
    Base * base = static_cast< Base * >( pv );
    return base->fnc( u1, pd, u2, d );
}

如果不是这种情况,并且您只想使用基类来确定要传递的函数而不传入&#34;这个&#34;,您可以使用虚函数来返回函数

class Base
{
 public:
    virtual integrand fcn() const = 0;
};