2013-02-26 135 views
0

我正在爲boost::signals2::signal編寫一個包裝函數,以獲得一個更乾淨,更易於使用的接口。這是我想出來的:如何傳遞信號回調函數(使用boost :: bind)

#include <boost/signals2.hpp> 

// Wrapper class template for boost::signals2::signal 
template<typename T> 
class Signal { 
    typedef typename boost::signals2::signal<T> SignalType; 
public: 
    // Trigger the signal 
    void operator()() { sig(); } 

    // Attach a listener 
    boost::signals2::connection operator+=(const typename SignalType::slot_type& slot) 
     { return sig.connect(slot); } 

private: 
    SignalType sig; 
}; 

class ClassThatGeneratesEvents { 
public: 
    void generateEvents(int n) { 
     while (n-- > 0) { 
      SomethingHappened(); 
     } 
    } 

    Signal<void()> SomethingHappened; 
}; 

void func() 
{ 
    ; 
} 

class ClassThatListensForEvents { 
public: 
    ClassThatListensForEvents(ClassThatGeneratesEvents& ev) { 
     received_count = 0; 

     // This works 
     ev.SomethingHappened += func; 

     // This doesn't! 
     ev.SomethingHappened += bind(&ClassThatListensForEvents::event_handler, this, _1); 
    } 

    void event_handler() { 
     received_count++; 
    } 

    int received_count; 
}; 

我不知道這是最好的封裝接口,我可以拿出,並製作SomethingHappened公共成員可能也許有一些缺點。雖然我不介意聽到你的意見,但這不是問題的關鍵。

我想知道的是如何將回調傳遞給+=運營商。正如我在ClassThatListensForEvents中所寫的那樣,函數的回調沒有問題,但使用結果bind會產生大量難以閱讀的模板編譯器錯誤。

+0

你開始寫這樣的包裝之前,這是值得一讀的[設計合理(http://www.boost.org/doc/libs/ 1_53_0/doc/html/signals/s06.html#idp161393904)部分。 – 2013-02-26 12:29:09

+0

我已經閱讀過一次,我同意它在Boost的通用上下文中,但在我的應用程序的上下文中,我是一個決定的人,我有點像那個乾淨的界面,缺點並不是我所關心的那裏。但'+ ='只是糖,編寫包裝器的真正原因是爲了從類的用戶隱藏'boost :: signals2 :: signal'類來降低複雜性並允許將來使用其他實現。 – Jonatan 2013-02-26 12:54:06

回答

3

你的信號有一個void()簽名,所以它不需要參數。您正嘗試分配一個boost::bind對象,該對象需要一個參數(因爲它使用的是_1),這是不兼容的。因此你會得到一個錯誤。目前尚不清楚你在哪裏期待ev參數到event_handler來自哪裏。如果綁定實際值而不是_1,則簽名將是兼容的。

+0

謝謝!那很愚蠢。 – Jonatan 2013-02-26 12:56:17

0

簽名信號和回調不同的,我認爲這是錯誤

+0

謝謝,但那只是一個沒有出現在實際代碼中的錯字。我已經更新了這個問題。 – Jonatan 2013-02-26 12:55:36

相關問題