Почему boost :: msm :: front :: state_machine может поддерживать до 10 состояний только для своей таблицы переходов?

Я пытаюсь настроить свой собственный конечный автомат с несколькими состояниями, средствами защиты и действиями, но когда число состояний в таблице переходов превышает 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

1

Решение

Компиляция с недавним повышением на компиляторе c ++ 11:

PS Не ругайте #define для псевдонимов типа

Жить на Колиру (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();
}
0

Другие решения

Других решений пока нет …