2015-01-07 40 views
0

Win 7的 cygwin的 GCC 4.8.3 -std = GNU ++ 11我如何通過一個函數作爲參數

我研究這個計算器上和CPLUSPLUS,以爲我會通過一個函數作爲一個正確的參數,即使'優雅',但很明顯,我誤解了一些東西。任何人都可以解釋如何正確地傳遞一個函數作爲參數,爲什麼我不會工作?

給出原型的單個警告和調用的單個錯誤。在評論中將genX更改爲genY,但genX和genY都具有相同的警告/錯誤。

class MyClass { 
    typedef double (*func_t)(double sum); 
    void driver(); 
    double genX(func_t fnc) { }; 
    double genY(double (*funct)(double sum)) { }; 
    // note: no known conversion for argument 1 from 
    // '<unresolved overloaded function type>' to 
    // MyClass::func_t {aka double (*)(double)} 
    double myThingie(double sum) { }; 
}; 

void MyClass::driver() { 
    genX(myThingie); 
    genY(myThingie); 
    // no matching function for call to 'MyClass::genX(<unresolved overloaded function type>)' 
} 

回答

4

"Can anyone explain how to pass a function as an argument correctly, and why what I have won't work?"

你需要

typedef double (MyClass::*func_t)(double sum); 
      // ^^^^^^^^ 

聲明函數指針成員類的功能。

,並得到他們喜歡

genX(&MyClass::myThingie); 
genY(&MyClass::myThingie); 
0

如果你堅持傳遞(C類,非成員)函數指針的地址,使用(特別是用於閱讀)一typedef(該class以外)申報其簽名:

typedef double func_sig_t(double); 

然後通過一個指針,例如

double genX(func_sig_t* fnc) { }; 

不過,我會用std::function

double genX(std::function<double(double)>); 

它不太便宜,但你可以通過一個lambda封閉,例如調用

double t; 
    double f = genX([=t](double x){return x+t;}); 

或者你想傳遞指針成員函數?他們有不同的語法!

+0

我認爲此答案不直接解決該問題。問題在於函數Op正在傳遞,因爲參數是一個實例方法,並且具有隱含的第一參數 –

1

您的聲明指出函數期望免費函數指針,而不是成員函數指針。其次,您提供的函數指針爲myThingie,它是MyClass的成員函數,但未提供實例。閱讀C函數指針,或者,如果可以的話,使用std::function獲得更多C++的ish解決方案。

1

嘗試使用以下

class MyClass { 
    typedef double (MyClass::*func_t)(double sum); 
    void driver(); 
    double genX(func_t fnc) { }; 
    double genY(double (MyClass::*funct)(double sum)) { }; 
    // note: no known conversion for argument 1 from 
    // '<unresolved overloaded function type>' to 
    // MyClass::func_t {aka double (*)(double)} 
    double myThingie(double sum) { }; 
}; 

void MyClass::driver() { 
    genX(&MyClass::myThingie); 
    genY(&MyClass::myThingie); 
    // no matching function for call to 'MyClass::genX(<unresolved overloaded function type>)' 
} 
+0

它可以工作(如您所期望的),但myThingie在MyClass中有作用域並且應該在驅動程序中可見。爲什麼我需要額外的參考?對於原始的typedef,由於它在MyClass中的作用域不應該是裸函數引用,並且使用:: *函數在MyClass之外作用域會更「正確」?或者這只是一個C++的東西? –

+0

@Arthur Schwarez GCC的以下錯誤消息解釋了這個問題:「錯誤:ISO C++禁止以非合格或加圓括號的非靜態成員函數的地址形成指向成員函數的指針,說'&MyClass :: myThingie'」 –

0

myThingie是一個成員函數 - 一個指向它的指針的類型爲double (MyClass::*)(double)
「成員指針」與常規指針完全不同,並且需要一個可以從中解除引用的合適類的實例。

您可以移動myThingie了之類的,使其成爲一個「自由」的功能,

class MyClass { 
    typedef double (*func_t)(double sum); 
    void driver(); 
    double genX(func_t fnc) { }; 
    double genY(double (*funct)(double sum)) { }; 
}; 

double myThingie(double sum) { }; 

或調整類型:

class MyClass { 
    typedef double (MyClass::*func_t)(double sum); 
    double genX(func_t fnc) { }; 
    double genY(double (MyClass::*funct)(double sum)) { }; 
    double myThingie(double sum) { }; 
}; 

void MyClass::driver() { 
    genX(&MyClass::myThingie); // The "MyClass::" is important here, too. 
    genY(&MyClass::myThingie); 
} 

在這種情況下,你需要使用「指向成員的「取消引用語法來調用該函數。
例如,

double genX(func_t fnc) { return (this->*fnc)(0.0) }; 
相關問題