【问题标题】:boost::statechart: How to define two sub states of certain state, without specifying which one is default?boost::statechart:如何定义某个状态的两个子状态,而不指定哪个是默认状态?
【发布时间】:2013-12-09 14:15:16
【问题描述】:

以下代码编译失败:

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 > { ... };

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

附:编译错误的一部分,我觉得很重要,说:simple_state.hpp:388: error: invalid application of ‘sizeof’ to incomplete type ‘boost_1_49_0::STATIC_ASSERTION_FAILURE&lt;false&gt;’,但这对我来说并没有什么意义。

【问题讨论】:

  • 转到“simple_state.hpp:388”行并查看那里的评论。

标签: c++ boost boost-statechart


【解决方案1】:

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

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

【讨论】: