In our project, we need a generic interface to refer to different state machine (back-end). For example, in the following codes, we want to use SMBase* to refer to any concrete state machine. SMBase should have similar interface as state machine.
struct User {
A(SMBase* s) : sm(s) ();
SMBase* sm;
...
// User can use sm->start(), sm->process_event() etc
}
struct SMBase
{
virtual void start() = 0;
... // how to design the rest ???
}
// a wrapper implement SMBase
template < typename SM >
class SMWrapper : public SMBase{
SMWrapper(SM & s): sm(s){};
virtual void start() { sm.start(); }
...
SM sm;
}
main()
{
typedef boost::msm::back::state_machine SM1;
typedef boost::msm::back::state_machine SM2;
User a1(new SMWrapper(SM1()) ); // Wrap the concrete state machine and pass it to User.
User a2(new SMWrapper(SM2()) ); // Pass a different state machine.
...
}
The problem of designing SMBase is the function "process_event". We want it to to be virtual function so SMWrapper can implement it. But it also needs to be a template according to state machine interface. But we cannot have a virtual template function.
How can we achieve/design this generic state machine interface?