1

I am using boost:msm to create a state machine. It seems when processing events, the state machine does not care about polymorphism.

Say I have multiple events all derived from a base event:

struct EvtBase { virtual ~EvtBase();}

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

Then if I have a bunch of events stored in a vector via pointers of base event type:

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

When I process these events by the state machine:

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

The boost::msm state machine thinks it receives EvtBase, rather than the actual event pointed by the pointer.

Am I doing something wrong, or is there a way to change this behavior and make process_event respect polymorphism?

4

1 回答 1

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);
}

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

于 2021-09-15T16:12:53.627 回答