1

I'm trying to implement a template for states machines in C++, but I'm not sure how to handle static object members. Each state machine would be defined by its state variables and its transitions (which are structs). For instance:

// stm.h

template <class T>
struct transition
{
    ... transition relevant data depending on state variables T ...
};

template <class T>
class stm
{
  T *stv; // state variables
  static struct transition<T> *transitions; // I would like to have only one copy of transitions for stm's of type T
  ... etc ...
};

Now, suppose I'm trying to implement the stm foo:

// foo_defs.h

struct foo_stv
{
  char a;
  int b;
};

// foo_transitions.h
// Note that I'm using a different file to keep everything in order

#include "stm.h"
#include "foo_defs.h"

struct transition<struct foo_stv> foo_transitions[] =
{
  { ... trans1 ... },
  ...,
  { ... transN ... }
};

// foo_stm.h

#include "stm.h"
#include "foo_defs.h"
#include "foo_transitions.h"

class foo_stm
{
  stm<struct foo_stv> stm;
  struct foo_stv stv;
  ... other data ...
};

Ok. So each instance of foo_stm should have a different set of state variables, but all instances should use the same transitions. The question is, how should I define/declare stm<struct foo_stv> in order to use foo_transitions as its class level transitions member?

Also any advice about C++ coding customs is welcome, since I come from the C coding world and just getting started with some C++ mechanics.

EDIT: Just to make clear my question, I guess you should forget about the stm logic and focus on the following: What's the correct way of doing something like...

foo_stm::stm.transitions = foo_transitions;
user2553780
  • 163
  • 8
  • why not a singleton pattern ? The problem will be that you can not initialize the static member except in the cpp, OR if you use recent c++. – dzada Sep 01 '13 at 21:48
  • 1
    *"Also any advice about C++ coding customs is welcome, since I come from the C coding world and just getting started with some C++ mechanics*" OK: `struct` keyword is not needed in C++ (Im talking about the sentences like `stm`. The only difference between `class` and `struct` is that the default scope of class members is private, in struct is public. – Manu343726 Sep 01 '13 at 22:11
  • "each instance of foo_stm should have a different set of state variables, but all instances should use the same transitions." How can you have different state variables and the same transitions? – BartoszKP Sep 01 '13 at 23:24
  • @BartoszKP Because the transition struct is composed of call back functions that use as one of its arguments the state vars of the instance stm. – user2553780 Sep 02 '13 at 02:44
  • @dzada Not sure if I could apply that to my particular problem, but I'll search info about it. Thanks. – user2553780 Sep 02 '13 at 02:45
  • @dzada first of all, [singleton is an antipattern](http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons) in the most cases which its used. Second: *"you cannot initialize the static member except in the cpp, OR if you use recent c++"* You could also initialize it in the header, bellow the class. – Manu343726 Sep 02 '13 at 07:25
  • @user2553780 I'm not sure if I understood you correctly, but doesn't this reveal a conceptual flaw in your design? State machine after all is defined by it's states and transitions. I'm also not sure if you aren't sometimes using the term "state variables" when you really mean "values of state variables" - could that be the case? – BartoszKP Sep 02 '13 at 07:45
  • @BartoszKP Yes, I mean that. When I said that it is "defined" by them I meant that one kind of state machine has one kind of state variables. One instance differs from other instance of that kind of stm on the current state and values of the state variables. Anyway, is it possible to initialize foo_stm.stm at global scope? If I was to do it in the constructor, how should I set foo_stm.stm.transitions to foo_transitions (included from foo_transitions.h)? – user2553780 Sep 02 '13 at 12:06
  • Have you considered Boost.MSM (http://www.boost.org/doc/libs/1_54_0/libs/msm/doc/HTML/index.html) or Boost.StateChart (http://www.boost.org/doc/libs/1_54_0/libs/statechart/doc/) instead of rolling your own state machine framework? – Sebastian Redl Sep 03 '13 at 12:03
  • @SebastianRedl Thanks for the recommendation, but as you said, I'm trying to build my own framework for stm's in C++ :) I want to keep things simple and controlled, and then add features as they are needed. – user2553780 Sep 03 '13 at 14:36

1 Answers1

2

All right, I think that what you want to do is:

template <class T>
class stm
{
  T *stv;
  static transition<T> *transitions;
};

template<class T>
transition<T>* stm<T>::transitions; //define static template member

And then:

//define static member for particular template instantiation
template<>
transition<foo_stv>* stm<foo_stv>::transitions = foo_transitions;

class foo_stm
{
  stm<struct foo_stv> stm;
  struct foo_stv stv;
  ... other data ...
};
BartoszKP
  • 32,105
  • 13
  • 92
  • 123
  • Interesting, I'll try this when I get home. I'm trying to desing in the context of OOP, but not used to it. Where am I failing? – user2553780 Sep 03 '13 at 14:39
  • 1
    I'll try to give you a more detailed answer soon, sorry for the delay. – BartoszKP Sep 04 '13 at 21:20
  • 1
    All right, I've analysed your solution more thoroughly and I think it's quite OK, in the context template programming. What I saw wrong the last time, was the fact that you're abusing a bit the "struct" keyword (C-style), and it blurred my vision a bit :-) Assuming that your `transition` structure contains a pair of states, and optionally some additional transition data all seems to be OK. Sorry for the misleading comment in my previous answer. – BartoszKP Sep 11 '13 at 22:26