I have these base classes to be extended and the goal was to provide some default implementation for unhandled events in the subclass.
struct Event {};
struct State {
void handle_event(const Event& e) {
std::cout << "State - generic event\n";
}
};
An example of a subclass implementation:
struct FlipSwitch : public Event {};
struct OtherEvent: public Event {};
class Light : public State {
public:
void handle_event(const FlipSwitch& e) {
std::cout << "Light - FlipSwitch event\n";
}
};
If I call:
Light *light = new Light();
light->handle_event(FlipSwitch()); // Works fine.
light->handle_event(OtherEvent()); // error: no matching function for call to
// ‘Light::handle_event(OtherEvent)’
If I define the default implementation on the subclass or add using State::handle_event; it fallbacks accordingly.
I expected that if the compiler didn´t find any function with 'OtherEvent' that would fallback to the generic defined in the base class just like it does when it's not inherited. I didn't expect the subclass to hide the method with a method with a different signature.
You can achieve the desired result by fixing your inheritance scheme and using dynamic casting in order to dispatch event processing to the right handler:
Live
First make
handle_eventa proper virtual function so that a inherited object will call its implementation. It will useEventobject of any concrete type. Then, in the overrided version, usedynamic_castto try to cast theEventobject to its actual class. Besides, I usedynamic_caston pointer, not reference, si that, if the requested type is not the correct one, it will returnnullptr, not throw an exception. Fordynamic_castto work,Eventmust be a polymorphic type, that is to say, a type that can be inherited. A way to tell that to the compiler is to declare at least one virtual function, here the destructor. If no valid type is recognised, I fall back to the default behavior, for instance, one that is implemented in the base class. Et voilà