我需要你的帮助,因为我不知道如何实现以下目标(而且根本不可能):
假设我有一个类层次结构,如
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(或者可能告诉我这是不可能的)?
提前谢谢!
答案 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
(因此您可以在Base
,Derived1
,{{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;
};