2016-06-28 99 views
1

我正在使用一個以C(library_function)編寫的外部庫的函數,該回調函數將回調函數作爲參數。庫調用回調函數的參數對我無關緊要。我唯一感興趣的是調用回調函數的順序。我希望回調函數在每次調用時都返回列表中的下一個元素。C++:具有狀態的回調函數

考慮這個例子:

#include <iostream> 

int x; 
bool *booleans; 

void library_function(bool(*callback_fn)()){ 
    for (int i=0; i < 5; i++) { 
     std::cout << callback_fn() << std::endl; 
    } 
} 

bool my_callback_fn(){ 
    return booleans[x++]; 
} 

void my_function(bool b[]){ 
    x = 0; 
    booleans = b; 

    library_function(my_callback_fn); 
} 

int main() { 
    bool booleans[] {true, false, true, true, false}; 
    my_function(booleans); 
} 

此代碼的工作,但我不得不使用全局變量,我認爲是不好的風格。

在Python例如,我會用一個內部函數來實現這一點:

def library_function(callback_fn): 
    for _ in range(5): 
     print(callback_fn()) 


def my_function(b): 
    x = -1 

    def my_callback_fn(): 
     nonlocal x 
     x += 1 
     return b[x] 

    library_function(my_callback_fn) 

if __name__ == '__main__': 
    booleans = [True, False, True, True, False] 
    my_function(booleans) 

我讀過,C++不支持nested functions和lambda函數只能被用作函數指針,如果他們不要capture variables

有沒有辦法避免使用全局變量,但仍然能夠修改回調函數的「內部狀態」?

在此先感謝!

+1

您可以對靜態變量使用靜態函數。 – Ari0nhh

+0

把狀態放入類中保持上下文。 –

+0

@ Ari0nhh:我試過了,但是當'my_function'被多次調用時,我沒有看到有機會將'i'重置爲'0'。如果您知道如何做到這一點,請隨時發佈答案。 @πάνταῥεῖ:謝謝,我試過了,它工作。我在下面發佈瞭解決方案。 – Felix

回答

1

我正在使用C(庫函數)編寫的外部函數庫,它以回調函數作爲參數。

除非外部庫允許您通過用戶定義的場景一樣喜歡

bool(*callback_fn)(void*) 
       // ^^^^^ 

提供回調簽名是有辦法避免使用全局變量,但仍然能夠修改「內部狀態'的回調函數?

除了使用全局上下文,沒有別的選擇。

0

嗯......這可能會幫助你

void fn() 
{ 
//tip: you can't use a struct in function to be a template argument. 
    struct _function 
    { 
    static void foo() 
     { 
     } 
    }; 
} 

,如果你有一個C++ 11的支持編譯器,你可以做到這一點

void(*)(int) fn() 
{ 
    return [&](int){code block};// for cast it to a function pointer you can not capture any variable in code block. 
} 
0

由於πάντα ῥεῖ的評論,我寫的一個持有我的回調函數狀態的類:

#include <iostream> 

void library_function(bool(*callback_fn)()){ 
    for (int i=0; i < 5; i++) { 
     std::cout << callback_fn() << std::endl; 
    } 
} 

class CallbackClass 
{ 
    static bool *booleans; 
    static int i; 

    static bool my_callback_fn(){ 
     return booleans[i++]; 
    } 

public: 
    static void my_function(bool b[]){ 
     i = 0; 
     booleans = b; 
     library_function(my_callback_fn); 
    } 
}; 

int CallbackClass::i {}; 
bool* CallbackClass::booleans {nullptr}; 


int main() { 
    bool booleans[] {true, false, true, true, false}; 
    CallbackClass::my_function(booleans); 
} 

這適用於我。

+1

您爲靜態變量交易全局變量,這幾乎沒有改進。 –