我应该在哪里定义状态机?: 为了简单起见,教程在一个简单的 cpp 源文件中实现。我想将一个类的动态行为建模为状态机,我应该如何定义状态机?
答案: 通常,您会希望将状态机实现为类的属性。不幸的是,具体的状态机是一个 typedef,无法前向声明。这为您留下两种可能性
问题: on_entry 获取作为参数,发送的事件。当状态变为默认激活(因为它是一个初始状态)时,我会收到什么事件?
答案: 为了让您知道状态已默认激活,MSM 生成一个 boost::msm::InitEvent 默认事件。
问题: 为什么我在我的子状态机中看不到对 no_transition 的调用?
答案: 由于 UML 定义的优先级规则。它规定,在转换冲突的情况下,最内层状态具有更高的优先级。因此,在询问内部状态后,也必须询问包含的组合状态来处理转换,并可能找到可能的转换。
问题: 为什么我会收到编译错误,说编译器无法转换为函数 ...Fsm::*(some_event)?
答案: 您可能定义了一个由事件 some_event 触发的转换,但使用了接受另一个事件的 guard/action 方法。
问题: 为什么我会收到编译错误,说类似“模板参数太少”或“模板参数太多”?
答案: 您可能以 a_row 或 g_row 的形式定义了一个转换,而您只想使用 _row 或反之亦然。对于 Row,这可能意味着您忘记了 “none”。
问题: 当我在转换表中定义超过 20 行时,为什么我会收到很长的编译错误?
答案: MSM 在底层使用 Boost.MPL,这是默认的最大大小。请在包含任何 MSM 标头之前定义以下 3 个宏
#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #define BOOST_MPL_LIMIT_VECTOR_SIZE 30 // or whatever you need #define BOOST_MPL_LIMIT_MAP_SIZE 30 // or whatever you need
问题: 为什么我会收到此错误:“error C2977: 'boost::mpl::vector' : 模板参数过多”?
答案: 第一种可能性是您将转换表定义为,例如,vector17 并且有 18 个条目。第二种可能性是您有 17 个条目并且有一个复合状态。在底层,MSM 为复合转换表中的每个事件添加一行。第三种可能性是您使用了没有条目数量的 mpl::vector,但接近 MPL 的默认值 50,并且有一个复合状态,因此将您推到 50 以上。那么您需要 mpl/vector60/70….hpp 和 mpl/map60/70….hpp
问题: 当我在状态机中定义超过 10 个状态时,为什么我会收到很长的编译错误?
答案: MSM 在底层使用 Boost.Fusion,这是默认的最大大小。请在包含任何 MSM 标头之前定义以下宏
#define FUSION_MAX_VECTOR_SIZE 20 // or whatever you need