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

3

我遇到了一个问题,即调用一个接受函数指针作为参数的全局函数。 下面是该全局函数的声明:

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)

很不幸,我遇到了一个编译器错误,它说: "error C2664: 'lmdif' : 无法将参数 1 从 'int (__thiscall LT_Calibrator::* )(void *,int,int,const double *,double *,int)' 转换为 'minpack_func_mn' 1> 没有上下文可以进行此转换"

有没有解决这个问题的方法?

3个回答

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);

3

本质上,成员函数有一个隐式参数(指向对象的this指针),这使得这个问题变得棘手。有关更多信息,请查看此FAQ条目


1

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

如果你的函数不需要访问 LT_Calibrator 实例,那么你可以简单地将其声明为静态函数,或者将其变为自由函数。否则,看起来你可以使用第一个参数 (void *p) 将实例指针传递到“跳板”函数中,然后调用成员函数。类似于这样的东西:

// 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, ...);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接