1

我的转换表和事件有问题。让我解释一下说明问题的假设计:

我有一个包含 2 个状态(s0 和 s1)和 1 个子状态机(subm1)的状态机(myStateMachine)。

子状态机 subm1 包含初始状态“sub0”和 s1(与 myStateMachine 中的状态相同)。

这是主要的转换表:

事件 'ES1' 上的 s0->s1

事件 'ES2' 上的 s0->s2

事件 'ESUB' 上的 s0->subm1

这是submachine转换表:

事件“ES1”上的 sub0->s1

现在,假设状态 s1 正在使用触发它的事件来提取一些信息,即

struct s1 : public msm::front::state<>
{
   template <class Event,class FSM>
   void on_entry(Event const& evt,FSM& fsm)
   { 
      evt.getEventData();
   }
}

所以每个可以转换到 s1 的事件都需要实现 getEventData() 方法。

-> 这是正常的!

现在我的问题是 ESUB 没有实现 getEventData() 但显然它应该(编译器给出错误)。我不明白为什么。

我没有使用 ESUB 转换到 s1,但我正在使用 ESUB 转换到 subm1,并且 subm1 包含 s1,但那时我没有访问它。

我希望这很清楚。

4

1 回答 1

2

我收到了 BOOST MSM 设计师 Christophe Henry 的答复:

“你好,

这是 msm(用于复合材料)的不幸限制,我在我的清单上列出了要尽快解决的问题。问题是虽然事件 esub 不用于转换到 s1,但对于编译器来说它可以。无论如何,这是我的错,而且我在文档中忘记了它:(

解决方案是通过为具有特殊属性的事件启用 on_entry evt.getEventData() 来帮助编译器,例如您的 es1。例如:

BOOST_MPL_HAS_XXX_TRAIT_DEF(get_event_data) 

// this event supports getEventData 
struct es1 
{ 
   typedef int get_event_data; 
   void getEventData(){...} 
 }; 

然后在您的状态下使用它:

 struct s1 : public msm::front::state<> 
 { 
   template <class Event,class FSM> 
   typename boost::enable_if<typename 
   has_get_event_data<Event>::type,void>::type 
   on_entry(Event const& evt,FSM& fsm) 
   { 
      evt.getEventData(); 
   } 
   // for events not supporting getEventData like esub 
   template <class Event,class FSM> 
   typename boost::disable_if<typename 
   has_get_event_data<Event>::type,void>::type 
   on_entry(Event const& ,FSM& ) 
   {    } 
   }; 

"

于 2012-09-28T16:26:30.807 回答