C ++ class function pointer as a global function parameter?

I am having a problem calling a global function that takes a function pointer as a parameter. Here is the global function declaration:

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

The symbol "minpack_func_mn" is a typedef for a pointer to a function defined as:

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

I want to call the "lmdif" function with a pointer to a function that is a member of the class I created, and here is the declaration of this class function:

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

I call the global function as follows:

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

Unfortunately, I get a compiler error saying: "error C2664: 'lmdif': cannot convert parameter 1 from 'int (__thiscall LT_Calibrator :: *) (void *, int, int, const double *, double *, int ) 'to' minpack_func_mn '1> There is no context in which this conversion is possible "

Is there any way to solve this problem?

+3
source share
3 answers

You need a non-member or a static member function; a member function pointer cannot be used in place of your function type because an instance is required to call it.

If your function does not need access to the LT_Calibrator instance, you can simply declare it static or make it free. Otherwise, it looks like you can use the first argument ( void *p ) to pass the instance pointer to the trampoline function, which can then call the member function. Something like that:

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

It seems to me that the lmdif function accepts "void * p" as a user argument, which it simply passes to the callback (minpack_func_mn fcn).

If so, just make LT_Calibrator :: fcn a static function and pass your object as the "p" parameter. You can then specify the user (p) argument to return your object if you want.

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

Then call like:

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

Essentially, there is an implicit argument for a member function ( this pointer) that makes this complicated. See this FAQ section for more information.

+3
source

All Articles