C++11 C+中可定制状态机(支持子状态)的编译时错误检查+;11 我正在使用C++ 11设计一个通用状态机。由于使用std::string标识状态,我只能在运行时捕获错误。我想更改它,以便在编译时在代码中指定状态时捕获错误

C++11 C+中可定制状态机(支持子状态)的编译时错误检查+;11 我正在使用C++ 11设计一个通用状态机。由于使用std::string标识状态,我只能在运行时捕获错误。我想更改它,以便在编译时在代码中指定状态时捕获错误,c++11,state,variadic-templates,C++11,State,Variadic Templates,我一直在玩一些基于可变模板和枚举类的想法,但还没有找到一个解决方案,至少不是一个相当干净/可读的解决方案 下面是我当前状态机的一些代码片段,完整的可运行代码位于: SState的构造函数为状态ID获取一个std::string,然后通过子状态的初始化列表初始化一个std::vector,如下所示: struct SState { SState(const std::string& str_id, const std::vector<SState>&a

我一直在玩一些基于可变模板和枚举类的想法,但还没有找到一个解决方案,至少不是一个相当干净/可读的解决方案

下面是我当前状态机的一些代码片段,完整的可运行代码位于:

SState
的构造函数为状态ID获取一个
std::string
,然后通过子状态的初始化列表初始化一个
std::vector
,如下所示:

struct SState {
   SState(const std::string& str_id,
          const std::vector<SState>& vec_sub_states = {}) :
      Id(str_id),
      SubStates(vec_sub_states) {
   }
   //...
   std::string Id;
   std::vector<SState> SubStates;
   //...
};
structstate{
SState(const std::string和stru id,
const std::vector&vec_sub_states={}):
Id(str_Id),
子状态(向量子状态){
}
//...
std::字符串Id;
std::向量子状态;
//...
};
然后可以使用以下语法进一步定义状态图:

方法

std::function<void()> fnInitFoo = [&] {
   std::cerr << "fnInitFoo" << std::endl;
   foo = 0;
};
sStateChart["init"]["init_foo"].SetEntryFunction(fnInitFoo);
std::function<bool()> fnTransInitFooInitBar = [&] {
   return (bar != 0);
};
sStateChart["init"].AddTransition("init_foo","init_bar", fnTransDisplayToInit);
std::函数fnInitFoo=[&]{

std::cerr这是一个编译过程,可能是一些有趣的事情的起点:

/* States */
enum class EState : unsigned int {
   FSM,
   INIT, INIT_FOO, INIT_BAR,
   COUNT, COUNT_FOO, COUNT_BAR,
   DISPLAY, DISPLAY_FOO, DISPLAY_BAR
};

template<EState STATE, class... SUBSTATES> class CState {};

int main() {

   CState<EState::FSM,
      CState<EState::INIT,
         CState<EState::INIT_FOO>,
         CState<EState::INIT_BAR>
      >,
      CState<EState::COUNT,
         CState<EState::COUNT_FOO>,
         CState<EState::COUNT_BAR>
      >,
      CState<EState::DISPLAY,
         CState<EState::DISPLAY_FOO>,
         CState<EState::DISPLAY_BAR>
      >
   > cStateMachine;

   return 0;
}

这将编译并可能成为有趣事情的起点:

/* States */
enum class EState : unsigned int {
   FSM,
   INIT, INIT_FOO, INIT_BAR,
   COUNT, COUNT_FOO, COUNT_BAR,
   DISPLAY, DISPLAY_FOO, DISPLAY_BAR
};

template<EState STATE, class... SUBSTATES> class CState {};

int main() {

   CState<EState::FSM,
      CState<EState::INIT,
         CState<EState::INIT_FOO>,
         CState<EState::INIT_BAR>
      >,
      CState<EState::COUNT,
         CState<EState::COUNT_FOO>,
         CState<EState::COUNT_BAR>
      >,
      CState<EState::DISPLAY,
         CState<EState::DISPLAY_FOO>,
         CState<EState::DISPLAY_BAR>
      >
   > cStateMachine;

   return 0;
}

你这样做只是为了教育目的吗?怎么样?部分是为了教育目的,即学习利用C++11中的新功能-我以前使用boost statechart编写过一个FSM,结果很难阅读…boost statechart和boost meta state machine是两个不同的库,不确定使用哪一个我将再看一次Meta状态机,我以前使用StestCalm。虽然我想避免在任何时候和任何地方使用标准C++,但是你是为了教育目的而做的吗?怎么样?部分是为了教育目的,即学习利用C++ 11中的新特性——我用Boost STA编写了一个FSM。TeCalk以前,它很难阅读…提高Stand图表和Beta状态机是两个不同的库,不确定你使用哪一个将在元状态机上另一个看,我以前使用StestCu图。尽管我想避免在任何时候和任何地方使用Buffic和使用标准C++。
/* States */
enum class EState : unsigned int {
   FSM,
   INIT, INIT_FOO, INIT_BAR,
   COUNT, COUNT_FOO, COUNT_BAR,
   DISPLAY, DISPLAY_FOO, DISPLAY_BAR
};

template<EState STATE, class... SUBSTATES> class CState {};

int main() {

   CState<EState::FSM,
      CState<EState::INIT,
         CState<EState::INIT_FOO>,
         CState<EState::INIT_BAR>
      >,
      CState<EState::COUNT,
         CState<EState::COUNT_FOO>,
         CState<EState::COUNT_BAR>
      >,
      CState<EState::DISPLAY,
         CState<EState::DISPLAY_FOO>,
         CState<EState::DISPLAY_BAR>
      >
   > cStateMachine;

   return 0;
}
cStateMachine.AddTransition(EState::COUNT_FOO, EState::COUNT_BAR);