从相同的两个不同模板副本继承时重载 class
Overloading when inheriting from two differently-templated copies of the same class
我正在为一款游戏编写一个输入处理系统,我想将其扩展到任意事件类型。我想设计一个类似接口的规范,允许我强制要求某些对象处理某些事件;例如通过 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()
的地方,上面的代码产生了以下错误。 EventHandler
的两个模板版本的 handleEvent()
似乎被视为相同的函数。我的印象是,由于 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 > {};
我正在为一款游戏编写一个输入处理系统,我想将其扩展到任意事件类型。我想设计一个类似接口的规范,允许我强制要求某些对象处理某些事件;例如通过 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()
的地方,上面的代码产生了以下错误。 EventHandler
的两个模板版本的 handleEvent()
似乎被视为相同的函数。我的印象是,由于 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 > {};