0

How i can call my method in upgrade() because it apears the error ' Error must use '.' or '->' to call pointer-to-member function'.

I want to have an Machine State, now i have the state monitor but i have a problem inside the upgrade() method.

template <class T>
  class StateMonitor {
  private:
    static const int MAXSTATES;
    static const int MAXLISTENERS;
    int internalState;
    int previousState;

    void* (T::*func_table[MAXSTATES_DEF][MAXSTATES_DEF])(int stFrom, int stTo);
    void* (T::*func_states[MAXSTATES_DEF])();
     
  public:
     
    StateMonitor();
    int addAction(int currentstate, void* (T::*handle)());
    void upgrade();
  
  };
template <class T> void  StateMonitor<T>::upgrade() {
  T::func_states[internalState]();
}
 template <class T> void StateMonitor<T>::addAction(int currentstate, void (T::*handle)()) { 
func_states[currentstate] = handle;
}

In a son class i call the method father, for example:

class Machine:public StateMonitor<Machine> {
private:
enum States {STATE_0=0,STATE_0=1};
public:
void* AccioSTATE_0(){/*some code to execute in current state*/};
void SetupGrafo(){
  addAction(STATE_0, AccioSTATE_0);
}
};

In the main loop, i want to create two objects of Machine class that have the same secuence:

Machine MachineA ;
void loop() {
  MachineA.upgrade(); //i want to execute the AccioSTATE_0
}
John
  • 23
  • 7
  • 2
    You have pointers to non-static member functions. You need an instance of `T` to call them on (just like you need an instance of `StateMonitor` to call `upgrade()` on). – Igor Tandetnik Feb 28 '21 at 18:58
  • Can you show me an example please? – John Feb 28 '21 at 19:01
  • 2
    Show how `StateMonitor` is supposed to be used. Prepare a [mcve]. – Igor Tandetnik Feb 28 '21 at 19:01
  • `addAction(STATE_0, AccioSTATE_0)` wouldn't compile, you'd need `addAction(STATE_0, &Machine::AccioSTATE_0)`. The call in `upgrade` would looks something like this: `T* p = static_cast(this); (p->*T::func_states[internalState])();` – Igor Tandetnik Feb 28 '21 at 21:17
  • @IgorTandetnik when i compile `(p->*T::func_states[internalState])();` inside upgrade the compiler shows an error `invalid use of non-static data member 'StateMonitor::func_states' ` – John Feb 28 '21 at 21:27
  • [Compiles for me](https://godbolt.org/z/8cs418). The code you compile must be somehow different. – Igor Tandetnik Feb 28 '21 at 21:31
  • @IgorTandetnik Thank you, in the same file thats works fine, but if i put in the cpp file like this form?: ` #include "StateMonitor.h" template const int StateMonitor::MAXSTATES = MAXSTATES_DEF; template void StateMonitor::upgrade() { T* p = static_cast(this); (p->*T::func_states[internalState])(); } ` it is correct? – John Feb 28 '21 at 21:53
  • [Why can templates only be implemented in the header file?](https://stackoverflow.com/q/495021/1670129) – Igor Tandetnik Feb 28 '21 at 21:54
  • @IgorTandetnik i put `(p->*T::func_states[StateMonitor::internalState])();` in the cpp file an i have the problem here. The header file of statemonitor.h ther i have correct. But i dont find the way to solve this problem – John Feb 28 '21 at 22:04
  • My code doesn't have `StateMonitor::` before `internalState`. Yours does. In fact, `T::` is also redundant - make it `(p->*func_states[internalState])();` – Igor Tandetnik Feb 28 '21 at 22:09

0 Answers0