Search code examples
c++templatesboost

Template states in boost:state_machine


I am pretty new with boost:state_machine, so sorry if my question does not make. I am trying to do implement a state_machine which is itself a template:

namespace sc = boost::statechart;

template <typename T>
class CMainStateMachine : public sc::state_machine< CMainStateMachine < T >, CStateA <T> >

friend class CStateA < T >;

public:

  CMainStateMachine(): 
  sc::state_machine< CMainStateMachine < T >, CStateA < T > > ()
  {
  }


template < typename T > 
class CStateA : public sc::state_machine < CStateA < T >, CMainStateMachine < T > >
{
  public:
  CStateA( my_context ctx ) : my_base(ctx)
  {
  }

when a try to compile it, it gives me next error:

expected ')' before 'ctx'

It seems the parenthesis are well balanced, so I have no idea what can be happening. Any suggestion?

Thank you in advance,

At least this basic example should compile.


Solution

  • As commented, it's not possible to reproduce your problem from the posted code. I came up with this - working - snippet trying to approximate your problem:

    Live On Coliru

    #include <boost/statechart/state_machine.hpp>
    namespace sc = boost::statechart;
    
    struct my_context {};
    template <typename> class CStateA;
    
    template <typename T> class CMainStateMachine : public sc::state_machine<CMainStateMachine<T>, CStateA<T>> {
        friend class CStateA<T>;
    
      public:
        CMainStateMachine() : sc::state_machine<CMainStateMachine<T>, CStateA<T>>() {}
    };
    
    template <typename T> class CStateA : public sc::state_machine<CStateA<T>, CMainStateMachine<T>> {
        using my_base = sc::state_machine<CStateA, CMainStateMachine<T>>;
    
      public:
        CStateA(my_context ctx) : my_base(ctx) {}
    };
    
    int main() {}
    

    Which compiles fine. Obviously you have another problem.

    Simplify

    Regardless of what concrete problem you had, I notice that there's a parallel "instantiation hierarchy" of machines and states by the same template argument.

    This should immediately give you the idea to simplify by combining both under a single template:

    template <typename T> struct SM {
        struct CStateA;
    
        struct CMainStateMachine : sc::state_machine<CMainStateMachine, CStateA> {
            friend struct CStateA;
            CMainStateMachine() : sc::state_machine<CMainStateMachine, CStateA>() {}
        };
    
        struct CStateA : sc::state_machine<CStateA, CMainStateMachine> {
            using my_base = sc::state_machine<CStateA, CMainStateMachine>;
            CStateA(my_context ctx) : my_base(ctx) {}
        };
    };
    

    this might remove all the future complexity!