我正在尝试使用多个状态,警卫和操作来设置我自己的状态机,但是当转换表中的状态数超过10个状态时,会弹出大量错误消息,但我仍然无法从中推断出错误的来源他们。我简化了我的代码:
/* Boost MSM */
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/back/mpl_graph_fsm_check.hpp>
/* STL */
#include <memory>
namespace msm = boost::msm ;
namespace msmf = boost::msm::front ;
namespace msmb = boost::msm::back ;
namespace mpl = boost::mpl ;
#define None \
msmf::none
namespace {
class Shelf_Hooking ;
// typedef msmb::state_machine<Shelf_Hooking> SM_ ;
typedef msmb::state_machine<Shelf_Hooking, msmb::mpl_graph_fsm_check> SM_ ;
struct Event {} ;
class Shelf_Hooking : public msmf::state_machine_def<Shelf_Hooking> {
/* States */
struct A ;
struct B ;
struct C ;
struct D ;
struct E ;
struct F ;
struct G ;
struct H ;
struct I ;
struct J ;
struct K ;
struct L ;
struct M ;
struct End ;
public:
Shelf_Hooking() {} ;
~Shelf_Hooking() {} ;
typedef A initial_state ;
struct transition_table : mpl::vector<
msmf::Row < A, Event, B, None, None >
, msmf::Row < B, None, C, None, None >
, msmf::Row < C, None, D, None, None >
, msmf::Row < D, None, E, None, None >
, msmf::Row < E, None, F, None, None >
, msmf::Row < F, None, G, None, None >
, msmf::Row < G, None, H, None, None >
, msmf::Row < H, None, I, None, None >
, msmf::Row < I, None, J, None, None >
, msmf::Row < J, None, K, None, None >
, msmf::Row < K, None, L, None, None >
, msmf::Row < L, None, M, None, None >
, msmf::Row < M, None, End, None, None >
>{} ;
private:
struct A : public msmf::state<> {} ;
struct B : public msmf::state<> {} ;
struct C : public msmf::state<> {} ;
struct D : public msmf::state<> {} ;
struct E : public msmf::state<> {} ;
struct F : public msmf::state<> {} ;
struct G : public msmf::state<> {} ;
struct H : public msmf::state<> {} ;
struct I : public msmf::state<> {} ;
struct J : public msmf::state<> {} ;
struct K : public msmf::state<> {} ;
struct L : public msmf::state<> {} ;
struct M : public msmf::state<> {} ;
struct End : public msmf::terminate_state<> {} ;
} ; /* End of State Machine class */
/***************************************************************/
/* Back-end */
class state_machine_impl{
std::unique_ptr<SM_> state_machine ;
public:
state_machine_impl()
: state_machine(new SM_()) {}
~state_machine_impl() {}
void runSM() {
state_machine->start() ;
state_machine->process_event( Event() ) ;
} /* End of runSM() */
} ; /* End of class state_machine_impl */
} /* End of namespace */
int main() {
std::unique_ptr<state_machine_impl> Sm_=
std::unique_ptr<state_machine_impl>(new state_machine_impl() ) ;
Sm_->runSM() ;
return 0 ;
}
如果我只将所有转换都转换为状态J,则转换表有效,但是一旦我添加从J到K的转换,编译器将抛出一个覆盖20,000。+行的错误。我的问题是:
如何在转换表中插入10个以上的状态,警卫和操作而不会产生任何错误?
提前谢谢!
编译器错误消息:
Scanning dependencies of target test_multiple_states
[ 86%] Building CXX object CMakeFiles/test_multiple_states.dir/src/test_multiple_states.cpp.o
In file included from /usr/include/boost/fusion/include/as_set.hpp:11:0,
from /usr/include/boost/msm/back/state_machine.hpp:28,
from /home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:2:
/usr/include/boost/fusion/container/set/convert.hpp: In instantiation of ‘struct boost::fusion::result_of::as_set<boost::mpl::s_item<{anonymous}::Shelf_Hooking::K, boost::mpl::s_item<{anonymous}::Shelf_Hooking::J, boost::mpl::s_item<{anonymous}::Shelf_Hooking::I, boost::mpl::s_item<{anonymous}::Shelf_Hooking::H, boost::mpl::s_item<{anonymous}::Shelf_Hooking::G, boost::mpl::s_item<{anonymous}::Shelf_Hooking::F, boost::mpl::s_item<{anonymous}::Shelf_Hooking::E, boost::mpl::s_item<{anonymous}::Shelf_Hooking::D, boost::mpl::s_item<{anonymous}::Shelf_Hooking::C, boost::mpl::s_item<{anonymous}::Shelf_Hooking::B, boost::mpl::s_item<{anonymous}::Shelf_Hooking::A, boost::mpl::set0<> > > > > > > > > > > > >’:
/usr/include/boost/msm/back/state_machine.hpp:1169:75: required from ‘class boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>’
/home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:94:29: required from here
/usr/include/boost/fusion/container/set/convert.hpp:27:13: error: invalid use of incomplete type ‘struct boost::fusion::detail::barrier::as_set<11>’
type;
^
In file included from /usr/include/boost/fusion/container/set/convert.hpp:11:0,
from /usr/include/boost/fusion/include/as_set.hpp:11,
from /usr/include/boost/msm/back/state_machine.hpp:28,
from /home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:2:
/usr/include/boost/fusion/container/set/detail/as_set.hpp:28:12: note: declaration of ‘struct boost::fusion::detail::barrier::as_set<11>’
struct as_set;
^
In file included from /home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:2:0:
/usr/include/boost/msm/back/state_machine.hpp: In instantiation of ‘boost::msm::back::state_machine<A0, A1, A2, A3, A4>::state_machine() [with A0 = {anonymous}::Shelf_Hooking; A1 = boost::msm::back::mpl_graph_fsm_check; A2 = boost::parameter::void_; A3 = boost::parameter::void_; A4 = boost::parameter::void_]’:
/home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:94:29: required from here
/usr/include/boost/msm/back/state_machine.hpp:1591:27: error: using invalid field ‘boost::msm::back::state_machine<A0, A1, A2, A3, A4>::m_substate_list’
,m_substate_list()
^
/usr/include/boost/msm/back/state_machine.hpp: In instantiation of ‘void boost::msm::back::state_machine<A0, A1, A2, A3, A4>::call_init<Event>::operator()(const boost::msm::wrap<State>&) [with State = {anonymous}::Shelf_Hooking::A; Event = boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::InitEvent; A0 = {anonymous}::Shelf_Hooking; A1 = boost::msm::back::mpl_graph_fsm_check; A2 = boost::parameter::void_; A3 = boost::parameter::void_; A4 = boost::parameter::void_]’:
/usr/include/boost/mpl/for_each.hpp:78:26: required from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::v_iter<boost::mpl::v_item<{anonymous}::Shelf_Hooking::A, boost::mpl::vector0<mpl_::na>, 0>, 0l>; LastIterator = boost::mpl::v_iter<boost::mpl::v_item<{anonymous}::Shelf_Hooking::A, boost::mpl::vector0<mpl_::na>, 0>, 1l>; TransformFunc = boost::msm::wrap<mpl_::arg<1> >; F = boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::call_init<boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::InitEvent>]’
/usr/include/boost/mpl/for_each.hpp:105:18: required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::v_item<{anonymous}::Shelf_Hooking::A, boost::mpl::vector0<mpl_::na>, 0>; TransformOp = boost::msm::wrap<mpl_::arg<1> >; F = boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::call_init<boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::InitEvent>]’
/usr/include/boost/msm/back/state_machine.hpp:1225:13: required from ‘void boost::msm::back::state_machine<A0, A1, A2, A3, A4>::start() [with A0 = {anonymous}::Shelf_Hooking; A1 = boost::msm::back::mpl_graph_fsm_check; A2 = boost::parameter::void_; A3 = boost::parameter::void_; A4 = boost::parameter::void_]’
/home/charly/My_programming_exercises/finite_state_machine/src/test_multiple_states.cpp:99:30: required from here
/usr/include/boost/msm/back/state_machine.hpp:2085:57: error: ‘boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::library_sm {aka class boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>}’ has no member named ‘m_substate_list’
execute_entry(::boost::fusion::at_key<State>(self->m_substate_list),evt,*self);
^
(...)
/usr/include/boost/msm/back/state_machine.hpp:671:58: error: ‘boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>::library_sm {aka class boost::msm::back::state_machine<{anonymous}::Shelf_Hooking, boost::msm::back::mpl_graph_fsm_check>}’ has no member named ‘m_substate_list’
(::boost::fusion::at_key<next_state_type>(fsm.m_substate_list),evt,fsm);
^
CMakeFiles/test_multiple_states.dir/build.make:62: recipe for target 'CMakeFiles/test_multiple_states.dir/src/test_multiple_states.cpp.o' failed
make[2]: *** [CMakeFiles/test_multiple_states.dir/src/test_multiple_states.cpp.o] Error 1
CMakeFiles/Makefile2:400: recipe for target 'CMakeFiles/test_multiple_states.dir/all' failed
make[1]: *** [CMakeFiles/test_multiple_states.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
答案 0 :(得分:0)
使用c ++ 11编译器编译最近的提升:
PS 不要滥用
#define
类型别名
Live On Coliru (Clang)
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/back/mpl_graph_fsm_check.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <memory>
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace msmb = boost::msm::back;
namespace mpl = boost::mpl;
using None = msmf::none;
namespace {
class Shelf_Hooking;
// typedef msmb::state_machine<Shelf_Hooking> SM_ ;
typedef msmb::state_machine<Shelf_Hooking, msmb::mpl_graph_fsm_check> SM_;
struct Event {};
class Shelf_Hooking : public msmf::state_machine_def<Shelf_Hooking> {
/* States */
struct A;
struct B;
struct C;
struct D;
struct E;
struct F;
struct G;
struct H;
struct I;
struct J;
struct K;
struct L;
struct M;
struct End;
public:
Shelf_Hooking(){};
~Shelf_Hooking(){};
typedef A initial_state;
struct transition_table : mpl::vector<
msmf::Row<A, Event, B, None, None>,
msmf::Row<B, None, C, None, None>,
msmf::Row<C, None, D, None, None>,
msmf::Row<D, None, E, None, None>,
msmf::Row<E, None, F, None, None>,
msmf::Row<F, None, G, None, None>,
msmf::Row<G, None, H, None, None>,
msmf::Row<H, None, I, None, None>,
msmf::Row<I, None, J, None, None>,
msmf::Row<J, None, K, None, None>,
msmf::Row<K, None, L, None, None>,
msmf::Row<L, None, M, None, None>,
msmf::Row<M, None, End, None, None> > {};
private:
struct A : public msmf::state<> {};
struct B : public msmf::state<> {};
struct C : public msmf::state<> {};
struct D : public msmf::state<> {};
struct E : public msmf::state<> {};
struct F : public msmf::state<> {};
struct G : public msmf::state<> {};
struct H : public msmf::state<> {};
struct I : public msmf::state<> {};
struct J : public msmf::state<> {};
struct K : public msmf::state<> {};
struct L : public msmf::state<> {};
struct M : public msmf::state<> {};
struct End : public msmf::terminate_state<> {};
}; /* End of State Machine class */
/***************************************************************/
/* Back-end */
class state_machine_impl {
std::unique_ptr<SM_> state_machine;
public:
state_machine_impl() : state_machine(new SM_()) {}
~state_machine_impl() {}
void runSM() {
state_machine->start();
state_machine->process_event(Event());
} /* End of runSM() */
}; /* End of class state_machine_impl */
} /* End of namespace */
int main() {
std::unique_ptr<state_machine_impl> Sm_ = std::unique_ptr<state_machine_impl>(new state_machine_impl());
Sm_->runSM();
}