2011-03-20 6 views
2

저는 JUCE를 x 플랫폼 프레임 워크로 사용하고 있으며 버튼/콤보 박스 등의 콜백을 특정 처리기 기능에 매핑하는 데 템플릿 수신기 클래스를 사용하고 있습니다. 다른 위젯이 자신의 콜백 함수 이름을 가지고 있기 때문에, 나는 다음과 같은 구조를 사용템플릿이있는 "Listener"처리기 모호성 문제

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 (Button *, ...)와 addHandler (Label *, ...)를 구별 할 수없는 것처럼 addHandler 호출 사이에 모호성이 발생합니다 !! 이 함수들은 템플릿으로 인해 프로토 타입이 다르므로 컴파일러가 왜 저에게 힘든 시간을 주는지 잘 모르겠습니다. 아이디어? 때문에 요청에

편집 :

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; 
}; 

A :

다른 청취자가있는 클래스처럼 보일 수 있습니다

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

+0

을 입력하고 오류가 발생한 행을 나타냅니다. –

+0

및 인스턴스화에 사용 된 코드 – log0

답변

0

편집
이 좋아, 모든 것을 다시 생각 후, 문제는 Button* 매개 변수 ListenerBase<MyClass, Button>ListenerBase<MyClass, Label> 각각 서로 다른 서명이 비록 때문에 상속의 과부하로 계산하는 것 같지 않는 addHandler 기능을 정의 (하나있다 다른 하나는 Label*입니다. (I는 기본 클래스를 거라고 typedef, 편의를 위해) 내가 이것을 발견 한 가지 가능한 수정은 완전히 정말로 원하는 있었는지 자세한 정보와 아마, addHandler에 조금 전화를받을 것입니다,하지만 작동합니다

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; 
}; 

'nother 편집
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

+0

@ 에릭 : 네 말이 맞아, 내가 너무 빨리 행동 했어. 내가 이걸 생각해 보자. – Xeo

+0

@Erik : 업데이트되고 재미있게도, 문제는 "ListenerBase가 다른 템플릿 인수로 인스턴스화되었습니다. 서로 다른 클래스입니다." :) – Xeo