【问题标题】:boost msm cannot processing polymorphic event?boost msm 无法处理多态事件?
【发布时间】:2021-09-15 07:45:41
【问题描述】:

我正在使用 boost:msm 创建状态机。似乎在处理事件时,状态机并不关心多态性。

假设我有多个事件都源自一个基本事件:

struct EvtBase { virtual ~EvtBase();}

struct EvtA : EvtBase {};
struct EvtB : EvtBase {};

如果我通过基本事件类型的指针将一堆事件存储在向量中:

typedef std::shared_ptr<EvtBase> ptrEvt;
std::vector<ptrEvt> event_list {std::make_shared<EvtA>(), std::make_shared<EvtB>()};

当我通过状态机处理这些事件时:

for (const auto& pEvt: event_list) {
    fsm.process_event(*pEvt);
}

boost::msm 状态机认为它接收到EvtBase,而不是指针指向的实际事件。

我做错了什么,还是有办法改变这种行为并使process_event尊重多态性?

【问题讨论】:

  • 运行时多态性和编译时不能很好地混合在一起。我认为你应该考虑 std::variant
  • @AlessandroTeruzzi 好建议,但不幸的是我不能使用 c++17。
  • 你可以使用 boost::variant 来代替
  • @AlessandroTeruzzi 好电话,确实有效。

标签: c++ boost boost-msm


【解决方案1】:

正如@Alessandro Teruzzi 使用boost::variant 所建议的那样(由于缺少c++17),这就是我所做的:

#include "boost/variant.hpp"

// A typedef of boost::variant, put all event here
typedef boost::variant<EvtA, EvtB, EvtC> EvtType;

// This is the static visitor functor, I use it to store a pointer to fsm as 
// well because I don't know how to make operator() take a second parameter
template <class FSM>
class ProcessEvent : boost::static_visitor<> {
public:
  ProcessEvent(FSM* pfsm) : pFsm(pfsm) {}  // used to pass in pointer to fsm

  template <class Event>
  void operator()(Event& evt) const {
    pFsm->process_event(evt);
  }

private:
  FSM* pFsm;
} // ProcessEvent

// This is the function I actually call
template <class FSM>
void fsm_process_event(FSM& fsm, EvtType v) {
  ProcessEvent<FSM> fsm_process_event(&fsm);
  boost::apply_visitor(fsm_process_event, v);
}

所以当我有一个事件向量时,我可以这样做:


for (const auto& evt: EventList) {
  fsm_process_event(some_fsm, evt);
}

我验证了状态机确实可以正常工作。

【讨论】:

  • +1 用于回答您自己的问题;我建议使用 c++14(以及最近的 Boost)你可以简化很多:pastebin.ubuntu.com/p/w8drD8stMJ
  • @sehe 好建议!我以为我必须使用继承自 boost:static_visitor 的仿函数作为访问者,但显然 Lambda 也可以!
猜你喜欢
  • 1970-01-01
  • 2019-10-06
  • 2011-04-25
  • 2013-05-22
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 2023-02-24
  • 1970-01-01
相关资源
最近更新 更多