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(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>'
4

1 回答 1

0

编辑好吧,在重新考虑一切之后,
问题在于每个都定义了一个函数,由于继承,这似乎不能算作重载,即使它们有不同的签名(一个带有参数,另一个带有参数)。我为此找到的一个可能的解决方法是完全限定对 的调用,有点冗长,也许不是真正想要的,但它有效(为方便起见,我使用了基类):ListenerBase<MyClass, Button>ListenerBase<MyClass, Label>addHandlerButton*Label*addHandlertypedef

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

'另一个编辑感谢这里对我的问题
的快速回答,我可以再给它一个编辑。那里提到的方法也适用于您的问题。:)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;
};
于 2011-03-20T12:18:52.270 回答