指向C ++类成员函数的指针作为全局函数的参数?

时间:2010-03-17 14:39:03

标签: c++ function-pointers

我遇到调用全局函数的问题,该函数将指向函数的指针作为参数。 以下是全局函数的声明:

int lmdif ( minpack_func_mn fcn, void *p, int m, int n, double *x, 
            double *fvec, double ftol)

“minpack_func_mn”符号是指向函数的指针的typedef,定义为:

typedef int (*minpack_func_mn)(void *p, int m, int n, const double *x, 
              double *fvec, int iflag );

我想用一个指向函数的指针调用“lmdif”函数,该函数是我创建的类的成员,这里是这个类函数的声明:

int LT_Calibrator::fcn(void *p, int m, int n, const double *x, 
                       double *fvec,int iflag)

我正在调用这样的全局函数:

info=lmdif(&LT_Calibrator::fcn, 0, m, n, x, fvec, ftol)

不幸的是,我收到编译错误,其中说: “错误C2664:'lmdif':无法将参数1从'int(__thiscall LT_Calibrator :: *)(void *,int,int,const double *,double *,int)'转换为'minpack_func_mn' 1 GT;没有可以进行此转换的上下文“

有没有办法解决这个问题?

3 个答案:

答案 0 :(得分:4)

在我看来,lmdif函数将“void * p”作为用户参数传递给它,它只是传递给回调(minpack_func_mn fcn)。

如果是这种情况,只需将LT_Calibrator :: fcn设为静态函数,并将对象作为“p”参数传递。然后,如果需要,可以转换用户参数(p)以使对象返回。

class LT_Calibrator
{
public:
  static int fcn(void *p, int m, int n, const double *x, double *fvec,int iflag)
  {
      LT_Calibrator* pCalibrator = static_cast<LT_Calibrator*>( p );
  }
};

然后打电话给:

LT_Calibrator someCalibrator;

info=lmdif(&LT_Calibrator::fcn, &someCalibrator, m, n, x, fvec, ftol);

答案 1 :(得分:3)

基本上,成员函数(this指针)有一个隐式参数,这使得这很棘手。有关详细信息,请查看this FAQ entry

答案 2 :(得分:1)

您需要非成员或静态成员函数;成员函数指针不能用于代替您的函数类型,因为它需要一个实例来调用它。

如果您的函数不需要访问LT_Calibrator实例,那么您可以简单地将其声明为静态,或使其成为自由函数。否则,看起来你可以使用第一个参数(void *p)将实例指针传递给“trampoline”函数,然后可以调用成员函数。有点像这样:

// member function
int LT_Calibrator::fcn(int m, ...);

// static (or non-member) trampoline
static int fcn_trampoline(void *p, int m, ...)
{
    return static_cast<LT_Calibrator*>(p)->fcn(m,...);
}

info = lmdif(&fcn_trampoline, this, m, ...);