2012-11-07 55 views
3

我想創建一個簡單的信號/插槽系統在C + +沒有助力,但我有一些問題,當我嘗試使用它的參數,這裏是我的代碼:std ::函數和信號/槽系統

我的信號類:

template <typename T> 
class Signal 
{ 
private: 
    typedef std::function<T> Slot; 

public: 
    Signal(); 

    void connect(Slot slot); 
    void emit(T data); 
    void emit(); 

private:  
    std::vector<Slot> slots;  
}; 

我的測試類:

class Object 
{ 
public: 
    Object(); 
    void sayHello( int i ); 
}; 

所以,我用我的課這樣的:

Signal<void(int)> signal; 
signal.connect(std::bind(&Object::sayHello, player, std::placeholders::_1)); 
signal.emit(0); 

我有在Signal.cpp警告: 一個候選功能並不可行:從「無效(*)(INT)」到「廉政」的第一個參數沒有已知的轉換;

在此代碼:

template <typename T> 
void Signal<T>::emit(T data) 
{ 
    typename std::vector<Slot>::iterator i; 
    Slot t; 

    for(i = this->slots.begin(); i != this->slots.end(); i++) 
    { 
     t = (*i); 
     t(data); // Here 
    } 
} 

我該如何解決呢?如果我想給我的「發射」方法提供一個對象或多個參數,hoc可以嗎?

謝謝!

+0

是[this](http://liveworkspace.org/code/2d733163b1af460eedcf05a7fb760608)你正在嘗試什麼?你指定'T' =='void(int)',但'emit'似乎期望'T' =='int'。 – ildjarn

+0

Oups!謝謝,那個工作更好,確實:) – Dono

回答

5

採摘從Signal類三行:

template <typename T> 
    // ... 
    typedef std::function<T> Slot; 
    // ... 
    void emit(T data); 

和你的信號的聲明:

Signal<void(int)> signal; 

答案應該是很明顯的:void emit(T)成爲void emit(void(*)(int))(函數類型,如void(int)轉化爲當它們是函數參數時指針)。

我只是推薦使用相同的方式使用T<Signature>的每個班級模板都是:部分專業化。

template<class Sig> 
class Signal; 

template<class R, class... Args> 
class Signal<R(Args...)>{ 
    // ... 
    typedef std::function<R(Args...)> Slot; 
    // ... 
    void emit(Args... args) const{ 
    // iterate over slots and call them, passing `args...` 
    } 
}; 
+0

'emit'似乎沒有使用任何東西的返回類型,所以也許應該假設'void'? – ildjarn

+0

@ildjarn:我仍在思考什麼是最好的行動方式。假設'無效'就是其中之一,但不會改變我的答案。我也在考慮一個combinator參數,它可以傳遞給'emit'並且將結果值(如摺疊)組合起來,或者將它們傳遞給某個地方。 – Xeo

+0

噢,謝謝,我在這裏學到了很多東西,並且完美地工作:D。我會在C++中閱讀更多關於變量參數的模板。 – Dono