boost :: statechart:如何定义某个状态的两个子状态,而不指定哪一个是默认状态?

时间:2013-12-09 14:15:16

标签: c++ boost boost-statechart

以下代码无法编译:

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 >();
}

问题似乎是Active状态必须在他们的定义中指定他们的子状态。就像我执行以下操作一样:

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

编译结果成功。我可以避免指出默认状态吗?

P.S。编译错误的一部分,我认为是必不可少的,说:simple_state.hpp:388: error: invalid application of ‘sizeof’ to incomplete type ‘boost_1_49_0::STATIC_ASSERTION_FAILURE<false>’,但它对我说的并不多。

1 个答案:

答案 0 :(得分:1)

如果没有其中一个是默认值,你就不能拥有子状态。这不是对状态图的限制,而是状态机概念的一部分。想象一下,您转换到Action,根据定义,还必须输入一个子状态,并且SM必须知道要输入哪个子状态。

如果没有逻辑默认值并且您始终显式转换为叶状态,那么确实不需要是默认值,但状态图仍然需要默认值。您始终可以创建默认情况下不执行任何第三个子状态。如果您从未转换到Active,而是直接转换为state_1state_2,那么您的虚拟默认状态无论如何都会被优化掉,所以这是一个很好的解决方法。