2012-06-07 23 views
1

我試圖在類中存儲回調。目前,我做這樣的事情:通用回調

struct Callback { 
    Callback (std::function<void()> func) : func_ (func){} 
    void call() const { func(); } 

private: 
    std::function<void()> func_; 
}; 

正如你所看到的,只是功能的特定類型(目前沒有回報,沒有參數)都可以使用。

有沒有什麼辦法可以像這樣使用這樣的類,在哪裏通過它來調用它?

void increment (int &n) { 
    ++n; 
} 

int main() { 
    int someNum = 5; 
    Callback callback (increment, someNum); //will call `increment (someNum);` 
} 

我想用一個參數包存儲的參數,並且typename存儲的返回類型,然後做一個std::function<ReturnType (Args)> callback_之類的事情,並且用類似callback_ (givenArgs...);調用它。然而,我對模板做的不夠了解,甚至不知道是否有可能。

真正的使用我會擺脫這個(至少現在)是一個計時器,但也許一個小的generic_function<>類包裝std::function<>將幫助更多。在這個例子中,雖然,暫停和取消暫停計時器每2秒:

void togglePause (Countdown &c) { 
    c.togglePause(); 
} 

int main() { 
    Countdown main (10000); //create countdown of 10s 
    Countdown delay (2000, togglePause, main); //this one calls func when expired 

    for (; !main.expired();) { //go while unpaused time < 10s 
     delay.wait().reset(); //wait 2s, call callback, reset back to 2s 
    } 
} 

當然,這可以應用到其他概念一樣好,但我不知道如何去在實現這一語法第一名。如果返回類型爲void,那麼我可以構建兩種不同的表單,但從一個不相關的上一個問題中可以看出,但是存儲具有任意數量和類型的參數的函數會讓我感到困惑。如果可能的話,我該如何使用這樣的語法?如果不是,語法會有多接近?

+1

我一直在這條路上,雖然不是用C++ 11(實際上它應該使它更容易)。留意[不可見調用約定](http://stackoverflow.com/q/9729438/21475)。 – Cameron

+0

@Cameron,謝謝你的提醒。我必須留意這一點,因爲我毫無疑問會在路上嘗試winapi的功能,並讓它感到困惑。 – chris

+0

你的平臺是什麼? (MSVC++?GCC?x86或x64?) – Cameron

回答

5

我覺得你只是想使用std ::綁定到你的功能轉換與參數成函數不帶參數:

int main() { 
    int someNum = 5; 
    std::function<void (void)> boundFunc = std::bind(increment, std::ref(someNum)); 
    Callback callback (boundFunc); //will call `increment (someNum);` 
} 

請注意,您需要的std ::裁判,以確保someNum是通過引用傳遞,並且您需要確保someNum保持在比回調更長的範圍內。

+0

它看起來應該起作用(好想法),但不幸的是它沒有。不過,這可能是我。看到我更新的問題。 – chris

+0

我剛剛更新了這個需要的std :: ref –

+0

是的,當我看到它時,我很嘈雜地呻吟着。它與測試用例完美結合,所以我可以假設它會在我實現它的時候。非常感謝。這比我想的要簡單得多。我總是設法找到最枯燥的做事方式。 – chris