Указатель на функцию-член класса C ++ в качестве параметра глобальной функции? - PullRequest
3 голосов
/ 17 марта 2010

У меня проблема с вызовом глобальной функции, которая принимает указатель на функцию в качестве параметра. Вот объявление глобальной функции:

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> Нет контекста, в котором это преобразование возможно "

Есть ли способ решить эту проблему?

Ответы [ 3 ]

4 голосов
/ 17 марта 2010

Мне кажется, что функция 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 голосов
/ 17 марта 2010

По сути, существует неявный аргумент для функции-члена (указатель this), который делает это сложным. Проверьте эту запись FAQ для получения дополнительной информации.

1 голос
/ 17 марта 2010

Вам нужна функция, не являющаяся членом или статическая; указатель на функцию-член не может использоваться вместо типа вашей функции, потому что он требует экземпляра для вызова.

Если вашей функции не нужен доступ к экземпляру 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, ...);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...