2010-03-17 99 views
3

我有一個調用全局函數的問題,它將函數的指針作爲參數。 這裏是全局函數的聲明:指向作爲全局函數參數的C++類成員函數?

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

的「minpack_func_mn」符號是一個指向函數的類型定義,定義爲:

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':無法從「轉換爲int參數1(__thiscall LT_Calibrator :: *)(無效*,int,int,const double *,double *,int)'到'minpack_func_mn' 1>沒有上下文可以進行這種轉換「

有什麼辦法解決這個問題嗎?

回答

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

本質上有一個隱含的成員函數參數(this指針),這使得這個棘手。檢查出this FAQ entry欲知更多信息。

4

在我看來像lmdif函數取「空缺* 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);