2011-03-20 33 views
2

我使用JUCE作爲X平臺的框架,我使用的模板監聽類映射按鈕/組合框等回調到一定的處理函數。由於不同的小部件都有自己的回調函數的名字,我用以下結構:模板化的「監聽器」處理模糊問題

template<typename Type, typename Widget> 
class ListenerBase : public Widget::Listener 
{ 
public: 
    typedef void (Type::*TCallbackType)(void); 
protected: 
    void notifyCallback(Widget* notifier) 
    { 
    ... 
    } 
    void addHandler(Widget* notifier, TCallbackType callback) 
    { 
    notifier->addListener(this); 
    ... 
    } 
}; 

template<typename Type> 
class ButtonListenerHandler : public ListenerBase<Type, Button> 
{ 
protected: 
    void buttonClicked(Button* btn) 
    { 
    notifyCallback(btn); 
    } 
}; 

template<typename Type> 
class LabelListenerHandler : public ListenerBase<Type, Label> 
{ 
protected: 
    void labelTextChanged(Label* lbl) 
    { 
    notifyCallback(lbl); 
    } 
}; 

,它工作正常,只要我只用在我的課的處理專業化之一。當我使用一個以上,VC++ 2008抱怨不確定性之間的addHandler操作調用彷彿編譯器不能addHandler操作(按鍵* ...)和addHandler操作(標籤* ...)之間distiguish!這些功能是不同的原型由於被模板化的,所以我不知道爲什麼編譯器是給我一個困難時期。想法?

編輯因請求:

與不同的聽衆類可能看起來像:

MyClass::MyClass() 
{ 
... 
    addHandler(m_btn, &MyClass::buttonHandlerFunction); <<< error 
    addHandler(m_label, &MyClass::labelHandlerFunction); <<< error 
} 

和錯誤是::

class MyClass : public ButtonListenerHandler<MyClass> 
       , public LabelListenerHandler<MyClass> 
{ 
... 
    void buttonHandlerFunction(); 
    void labelHandlerFunction(); 

    Button* m_btn; 
    Label* m_label; 
}; 

其中錯誤出現

1>MyClass.cpp(287) : error C2385: ambiguous access of 'addHandler' 
1>  could be the 'addHandler' in base 'ListenerBase<MyClass,juce::Button>' 
1>  or could be the 'addHandler' in base 'ListenerBase<MyClass,juce::Label>' 
+0

請問您可以發佈完整的編譯器消息嗎? – Philipp 2011-03-20 11:26:27

+0

並指示哪條線路導致錯誤。 – 2011-03-20 11:36:39

+0

,並用於實例 – log0 2011-03-20 11:37:18

回答

0

編輯
好了,一切重新思考後,問題在於ListenerBase<MyClass, Button>ListenerBase<MyClass, Label>每個定義addHandler功能,因爲繼承這似乎並不算作超載,即使他們有不同的簽名(一用一Button*參數,另一個是Label*)。一個可能的修復,我發現這是完全的呼叫詳細,也許沒有資格addHandler,有點什麼真正需要的,但它的工作原理(爲方便起見,我typedef倒是基類):

template<class Type> 
class ButtonListenerHandler : public ListenerBase<Type, Button>{ 
public: 
    typedef ListenerBase<Type, Button> ButtonListenerBase; 
}; 

template<class Type> 
class LabelListenerHandler : public ListenerBase<Type, Label>{ 
public: 
    typedef ListenerBase<Type, Label> LabelListenerBase; 
}; 

class MyClass : public ButtonListenerHandler<MyClass>, 
       public LabelListenerHandler<MyClass>{ 
public: 
    void buttonHandlerFunction(); 
    void labelHandlerFunction(); 

    MyClass(){ 
     ButtonListenerHandler<MyClass>::addHandler(m_btn, &MyClass::buttonHandlerFunction); 
     LabelListenerHandler<MyClass>::addHandler(m_label, &MyClass::labelHandlerFunction); 
    } 

private: 
    Button* m_btn; 
    Label* m_label; 
}; 

「諾特爾編輯
得益於快速回答my question here,我可以給它一個編輯。那裏提到的using方法也適用於您的問題。 :)

class MyClass : public ButtonListenerHandler<MyClass>, 
    public LabelListenerHandler<MyClass>{ 
public: 
    using ButtonListenerHandler<MyClass>::addHandler; 
    using LabelListener<MyClass>::addHandler; 

    void buttonHandlerFunction(){ 
    } 
    void labelHandlerFunction(){ 
    } 

    MyClass(){ 
     addHandler(m_btn, &MyClass::buttonHandlerFunction); 
     addHandler(m_label, &MyClass::labelHandlerFunction); 
    } 

private: 
    Button* m_btn; 
    Label* m_label; 
}; 
+0

ListenerBase問題進行實例化不同的模板參數 - 它們是不同的類。 Widget :: Listener是雙重繼承的類。 – Erik 2011-03-20 12:26:34

+0

@Erik:你說得對,那是我的表現有點太快了......讓我試試這個。 – Xeo 2011-03-20 12:30:10

+0

@Erik:更新,足夠有趣,問題在於你說的「ListenerBase實例化了不同的模板參數 - 它們是不同的類」。 :) – Xeo 2011-03-20 12:51:41