从同一类的两个不同模板副本继承时重载

Overloading when inheriting from two differently-templated copies of the same class

本文关键字:副本 重载 继承 一类 两个      更新时间:2023-10-16

我正在为一个游戏编写一个输入处理系统,我想让它可扩展到任意事件类型。我想设计一个类似接口的规范,允许我强制某些对象应该处理某些事件;例如,通过类似 class Player : public EventHandler<KeyboardEvent> .我为这样的事情提出的设计如下。

template <class T>
class EventHandler {
public:
    void handleEvent(T event) { doHandleEvent(event); };
private:
    virtual void doHandleEvent(T event) {};
};
class InputHandler : public EventHandler<Action>, public EventHandler<CursorEvent> {};

但是,在我调用InputHandler::handle()的地方,上述内容会产生以下错误。似乎两个模板化版本的EventHandlerhandleEvent()被视为相同的函数。我的印象是,由于handleEvent的两个版本具有不同的参数类型,因此结果应该好像InputHandler有一个具有两种可能的参数类型的重载函数。

为什么C++不允许这样做,还有什么更好的替代方案来代替我正在尝试做的事情?我怀疑以上可能不是好的做法。

/Users/smichaels/Projects/danmaku/src/SDL/Input.cpp:35:34: error: member 'handleEvent' found in multiple base classes
      of different types
                if (act) handler.handleEvent(act.get());
                                 ^
/Users/smichaels/Projects/danmaku/src/SDL/../Input/InputHandler.hpp:15:14: note: member found by ambiguous name lookup
        void handleEvent(T event) { doHandleEvent(event); };
             ^
/Users/smichaels/Projects/danmaku/src/SDL/../Input/InputHandler.hpp:15:14: note: member found by ambiguous name lookup
class InputHandler :
  public EventHandler<Action>,
  public EventHandler<CursorEvent>
{
public:
  using EventHandler<Action>::handleEvent;
  using EventHandler<CursorEvent>::handleEvent;
};

在 C++17 中,您可以改为编写:

template<class...Bases>
struct ManyHandler:Bases...{
  using Bases::handleEvent...;
};
template<class...Events>
using EventsHandler=ManyHandler< EvendHandler<Events>...>;

然后

class InputHandler : public EventsHandler<Actions, CursorEvent >{};

如果你也有

class OutputHandler : public EventsHandler< Messages, Sounds >{};

我们可以写

class IoHandler : public ManyHandler< InputHandler, OutputHandler > {};