boost::statechart: How to define two sub states of certain state, without specifying which one is default?

StackOverflow https://stackoverflow.com/questions/20472756

  •  30-08-2022
  •  | 
  •  

Question

The following code fails to compile:

namespace sc = boost::statechart;

class Active;
class FSM : public sc::state_machine< FSM, startup>
{
};

class ev_1 : public sc::event<ev_1> {};
class ev_2 : public sc::event<ev_2> {};

class Active : public sc::simple_state< Active, FSM >
{
public:
    typedef boost::mpl::list<
        sc::custom_reaction< ev_1 >,
        sc::custom_reaction< ev_2 >
    > reactions;
    sc::result react( const ev_1 & );
    sc::result react( const ev_2 & );
};

class state_1 : public sc::simple_state< state_1, Active >
{
public:
    state_1(){};
    ~state_1(){};
};

class state_2 : public sc::simple_state< state_2, Active >
{
public:
    state_2(){};
    ~state_2(){};
};

sc::result startup::react( const ev_1 & )
{
    return transit< state_1 >();
}

sc::result startup::react( const ev_2 & )
{
    return transit< state_2 >();
}

The problem seems to be that Active state have to designate their child-state in their definition. Like if I do the following:

class Active : public sc::simple_state< Active, FSM, state_1 > { ... };

compilation result in success. Can I avoid to point-out default state?

P.S. Part of compilation error, which I found essential, says : simple_state.hpp:388: error: invalid application of ‘sizeof’ to incomplete type ‘boost_1_49_0::STATIC_ASSERTION_FAILURE<false>’ but it doesn't say a lot to me.

Was it helpful?

Solution

No you cannot have substates without one of them being the default. This is not a restriction from statecharts but rather part of the concept of state machines in general. Imagine that you transition to Action, by definition one of the substates must also be entered and the SM must know which to enter.

If there is no logical default and you always explicitly transition to leaf states then there dosn't really need to be a default but statecharts still needs a default. You can always create a do nothing third child state that is the default. If you never transition to Active but rather always to state_1 or state_2 directly then your dummy default state will get optimized away anyway so this is a good work around.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top