2014-04-02 34 views
2

我一直在研究如何將函數作爲參數傳遞給C++中的另一個函數。C++傳遞函數作爲參數,在某個點執行

我不確定我是否正確理解術語,因此我沒有在網上找到我正在尋找的內容。我認爲我可以更好地解釋它作爲一個問題。

我想通過一個函數作爲參數發生在它傳遞的函數中的某個點上。

下面是一些僞代碼,以更好地解釋我的查詢:

myNewFunction(passedFunction_1, passedFunction_2){ 

      //do some magic in OpenGL 
       execute passedFunction_1 
      //do some magic in OpenGL 
       execute passedFunction_2 
      //do some magic in OpenGL 
       execute passedFunction_1 (again) 
      //do some magic in OpenGL 
    } 

我希望你能理解。任何幫助,將不勝感激。提前致謝。

+0

你能澄清嗎?你只需要在C++中使用這種語法的幫助? – Lilshieste

+0

是的,非常。我已經有了我的功能。我只是試圖按照上面的函數的順序來實現一些東西。感謝您的評論。 – Reanimation

回答

2

因爲我們談論C++而不是C,你應該使用std::function。它是更安全,你也可以用它做更復雜的事情像測試的存在,結合/柯里...

#include <iostream> 
#include <functional> 

#using namespace std; 

typedef function<void (void)> tVoidFunction; 
typedef function<void (int)> tVoidFunctionTakingIntParameter; 
typedef function<int (float)> tIntFunctionTakingFloatParameter; 

void combinedFunction(tVoidFunction fvoid, tVoidFunctionTakingIntParameter fInt, tIntFunctionTakingFloatParameter fIntFromFloat){ 
    if (fvoid) { 
    fvoid(); 
    } 
    if (fInt && fIntFromFloat) { 
    static const float magicValue = 42.f; 
    int convertedValue = fIntFromFloat(magicValue); 
    fInt(convertedValue); 
    } 
} 

void helloWorld() { 
    cout << "Hello World" << endl; 
} 
int floatToInt(float f) { 
    return floor(abs(f)); 
} 
void doSomethingWithAnInt(int i) { 
    cout << "doSomethingWithAnInt: " << i << endl; 
} 
... 

void doWeirdThings() { 
    combinedFunction(helloWorld, doSomethingWithAnInt, floatToInt); 
} 

何說明爲什麼這是比C風格的函數指針更好,這裏有一對夫婦(有些人爲的)使用std::bind和lambda來做一些更有趣的功能性東西的例子:

struct Foo { 
    void doSomethingWithAnInt(int i) { 
    cout << "Foo instance @" << this << " got: " << i << endl; 
    } 
} 
int doSomethingWithTwoFloats(float f1, float f2) { 
    return floor(sqrt(abs(f1 + f2))); 
} 

... 

void doWeirderThingsThanBefore() { 
    Foo someFoo; 
    auto someFooDoesSomethingWithAnInt = bind(&Foo:doSomethingWithAnInt, &someFoo); 
    static const float anotherMagicValue = 69.f; 
    auto doSomethingWithTheMagicValue = bind(&doSomethingWithTwoFloats, anotherMagicValue); 
    auto helloLambda = [](){ 
    cout << "Hello, Lambda!" << endl; 
    }; 

    combinedFunction(helloLambda, someFooDoesSomethingWithAnInt, doSomethingWithTheMagicValue); 
} 
+0

這也是一個很好的例子。你是否能夠傳遞一個數組作爲函數的參數傳遞?例如:'typedef函數 newFunc' – Reanimation

+0

你可以使用你喜歡的任何函數簽名。 –

+0

真棒回答。這真的很棒。感謝發佈。 – Reanimation

0

定義myNewFunction以便它需要兩個其他功能。 passFunction1以及passFunction2是指向不需要參數且不返回任何內容的函數的指針。

void myNewFunction(void (*passFunction1)(), 
        void (*passFunction2()) 
{ 
    passFunction1(); 
    passFunction2(); 
    passFunction1(); 
} 

定義一個不帶參數,不做任何事情,並且不返回任何內容的函數。

void foo() 
{ 
    // Do something useful 
} 

定義另一個函數,它不接受任何參數,不做任何事情,也不返回任何內容。

void bar() 
{ 
    // Do something useful 
} 

呼叫使用的最後兩個函數的第一個函數。

myNewFunction(foo, bar); 
+0

關於函數的指針,它們是否可以存儲在任何東西中,以便在另一個函數中執行?我會在上面更新我的僞代碼。 – Reanimation

+0

是的,它們可以存儲以備將來使用。 –

+0

哦。我現在和你在一起。我想我明白。謝謝澄清。我現在就放棄它。感謝發佈。 – Reanimation

1

最新標準定義了std::function類做的正是這一點,可能是(特別是考慮到C函數指針的也許恐嚇語法)最簡單的方法。

語法將是這樣的:

myNewFunction(std::function<void()> passedFunction_1, std::function<void()> passedFunction_2){ 
     //do some magic in OpenGL 
      passedFunction_1(); 
     //do some magic in OpenGL 
      passedFunction_2() 
     //do some magic in OpenGL 
      passedFunction_1(); 
     //do some magic in OpenGL 
} 

實例化std::function通過識別,你想繞過函數來完成,就像你,如果你是使用原始的C函數指針(一個關於std::function的好處是它和C函數指針很好地搭配)。像下面這樣:

void do_stuff(std::function<void()> another_function) 
{ 
    // Doing stuff 

    another_function(); // Invoking the parameter 
} 

void something_extra() 
{ 
    // Does something else 
} 

int main() 
{ 
    std::function<void()> the_function = &something_extra; 

    // Invoke do_stuff, with something_extra as the function being passed in 
    do_stuff(the_function); 

    return 0; 
} 
+0

這很有趣。我也會放棄這一點。感謝發佈。很好的答案。 – Reanimation

相關問題