模板化的“监听器”处理程序歧义问题
我使用 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;
};
A 发生错误的地方:
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>'
I'm using JUCE as a x-platform framework, and I'm using template listener classes to map button/combobox etc. callbacks to certain handler functions. Since the different widgets have their own callback function name, I use the following structure:
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);
}
};
And it works fine, as long as I use only one of the handler specializations in my class. As soon as I use more than one, VC++ 2008 complains of ambiguity between the addHandler calls as if the compiler cannot distiguish between addHandler(Button*, ...) and addHandler(Label*, ...) !! These functions are of different prototypes due to being templatized, so I have no idea why the compiler is giving me a hard time. Ideas ?
Edit due to requests:
A class with different listeners may look like:
class MyClass : public ButtonListenerHandler<MyClass>
, public LabelListenerHandler<MyClass>
{
...
void buttonHandlerFunction();
void labelHandlerFunction();
Button* m_btn;
Label* m_label;
};
A where the error occurs:
MyClass::MyClass()
{
...
addHandler(m_btn, &MyClass::buttonHandlerFunction); <<< error
addHandler(m_label, &MyClass::labelHandlerFunction); <<< error
}
And the error is:
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>'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
编辑
好吧,重新考虑一下之后,问题出在
ListenerBase
和ListenerBase
各自定义了一个addHandler
函数,由于继承的原因,即使它们具有不同的签名(一个带有Button*
参数,另一个带有Label*
参数),它似乎也不算重载。我发现的一个可能的修复方法是完全限定对addHandler
的调用,有点冗长,也许不是真正想要的,但它有效(为了方便起见,我typedef
'd 基类):'另一个编辑
感谢对 的快速回答我的问题在这里,我可以再次编辑。其中提到的
using
方法也适用于您的问题。 :)Edit
Okay, after rethinking everything, the problem lies with
ListenerBase<MyClass, Button>
andListenerBase<MyClass, Label>
each defining anaddHandler
function, which because of inheritance doesn't seem to count as overloading, even though they have different signatures (one with aButton*
parameter, the other with aLabel*
one). One possible fix I found for this is to fully qualify the call toaddHandler
, a bit verbose and maybe not what was really desired, but it works (for convenience, Itypedef
'd the base classes):'nother Edit
Thanks to the fast answer to my question here, I can give it another edit. The
using
method mentioned there also applies to your problem. :)