以下代码无法编译:
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>’
,但它对我说的并不多。
答案 0 :(得分:1)
如果没有其中一个是默认值,你就不能拥有子状态。这不是对状态图的限制,而是状态机概念的一部分。想象一下,您转换到Action
,根据定义,还必须输入一个子状态,并且SM必须知道要输入哪个子状态。
如果没有逻辑默认值并且您始终显式转换为叶状态,那么确实不需要是默认值,但状态图仍然需要默认值。您始终可以创建默认情况下不执行任何第三个子状态。如果您从未转换到Active
,而是直接转换为state_1
或state_2
,那么您的虚拟默认状态无论如何都会被优化掉,所以这是一个很好的解决方法。