Reputation: 3
I'm writing an input-handling system for a game that I'd like to make extensible to arbitrary event types. I'd like to design an interface-like specification that allows me to enforce that certain objects are expected to handle certain events; for instance via something like class Player : public EventHandler<KeyboardEvent>
. My proposed design for such a thing is as follows.
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> {};
However, at the point where I call InputHandler::handle()
, the above produces the following errors. It appears that handleEvent()
for both templated versions of EventHandler
is treated as the same function. I was under the impression that since the two versions of handleEvent
have different argument types, the result should be as if InputHandler
had one overloaded function with the two possible argument types.
Why doesn't C++ allow this, and what are some better alternatives to what I'm trying to do? I suspect the above may not be good practice.
/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
Upvotes: 0
Views: 36
Reputation: 275760
class InputHandler :
public EventHandler<Action>,
public EventHandler<CursorEvent>
{
public:
using EventHandler<Action>::handleEvent;
using EventHandler<CursorEvent>::handleEvent;
};
in c++17 you can instead write:
template<class...Bases>
struct ManyHandler:Bases...{
using Bases::handleEvent...;
};
template<class...Events>
using EventsHandler=ManyHandler< EvendHandler<Events>...>;
then
class InputHandler : public EventsHandler<Actions, CursorEvent >{};
and if you also have
class OutputHandler : public EventsHandler< Messages, Sounds >{};
we can write
class IoHandler : public ManyHandler< InputHandler, OutputHandler > {};
Upvotes: 1