Boost logo

Boost Users :

Subject: Re: [Boost-users] [Boost Statechart Library] How to inherit reactions?
From: Michael Chisholm (chisholm_at_[hidden])
Date: 2012-02-17 12:39:22


On 2/17/2012 7:31 AM, Philipp Bender wrote:
> Hi,
>
> I'd like to define an abstract state which reacts to a specific event
> and calls a virtual hook function. In classes which inherit from my base
> class, I'd like to define those hooks.
>
> struct EvHeartBeat : boost::statechart::event<EvHeartBeat> {};
> struct EvMyFoo : boost::statechart::event<EvMyFoo> {};
>
> // this is my base class
>
> template< class MostDerived,
> class Context,
> class InnerInitial = boost::mpl::list<>,
> boost::statechart::history_mode historyMode =
> boost::statechart::has_no_history >
> struct BaseState :
> public boost::statechart::simple_state<
> MostDerived, Context, InnerInitial, historyMode >
> {
> typedef BaseState< MostDerived,
> Context, InnerInitial, historyMode > base_state;
>
> typedef boost::mpl::list<
> boost::statechart::custom_reaction< EvHeartBeat > > reactions;
>
> const std::string name;
>
> virtual boost::statechart::result hook() = 0;
>
> boost::statechart::result react ( const EvHeartBeat& e)
> {
> return hook();
> }
>
> };
>
> // this is my derived class
>
> struct B :
> BaseState<B, SomeContext, InitialState >
> {
> typedef boost::mpl::list<
> boost::statechart::custom_reaction<EvMyBar>
> > my_reactions;
>
> typedef boost::mpl::insert_range<my_reactions,
> boost::mpl::end<my_reactions>::type,
> BBFState::bbf_state::reactions>::type reactions;
>
> boost::statechart::result react ( const EvMyFoo& )
> {
> std::cout << "B's reaction" << std::endl;
> }
>
> };
>
> The derived class needs some explanation: I want it to react to other
> events as well, therefore the my_reactions typedef. Then I merge the
> mpl::list reactions from base and derived, this is a bit ugly but should
> be a generic way to do get the desired result.
>
> Now the problem: My compiler (g++-4.4) complains that there is no
> B::react( const EvHeartBeat& ) method. But it should, it's in the parent
> class. Furthermore, if I _remove_ the reaction to the other event, it
> compiles and actually uses the parent's reaction method.
>
> Of course I can find a workaround (including some boiler plate code),
> but as this will be an integral part of my project, I'd like it to be as
> correct, maintainable and elegant as possible.
>
> I'd be happy to get some opinions about what's wrong here, best regards
> Philipp

Looks to me like a language issue. Adding a method overload to the
derived class does not augment the ones from the base class, it masks
them. If you want to bring the parent methods into scope in the derived
class to extend the overload set there, you can use a 'using' declaration:

struct B : BaseState<...>
{
   using BaseState<...>::react;
   boose::statechard::result react(...) {...}
};

I'm no C++ guru, but I think that's just how the language works.

Andy


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net