我正在使用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(Button *,...)和addHandler(Label *,...)之间进行抛弃!这些函数由于被模板化而具有不同的原型,所以我不知道为什么编译器给我带来了困难。想法?
由于请求而编辑:
具有不同侦听器的类可能如下所示:
class MyClass : public ButtonListenerHandler<MyClass>
, public LabelListenerHandler<MyClass>
{
...
void buttonHandlerFunction();
void labelHandlerFunction();
Button* m_btn;
Label* m_label;
};
发生错误的地方:
MyClass::MyClass()
{
...
addHandler(m_btn, &MyClass::buttonHandlerFunction); <<< error
addHandler(m_label, &MyClass::labelHandlerFunction); <<< error
}
错误是:
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 :(得分: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;
};