-1

This is a part of Arduino program(C++). MCU is ESP32.

I have defined a class. Inside it I have created an array of member functions.

class IRDN_Padidar_Zone
{
bool callAnimation();  
uint16_t Animate_None(enum_Effect inOut);
uint16_t Animate_Print(enum_Effect inOut);
uint16_t Animate_Print_Random(enum_Effect inOut);
uint16_t Animate_Print_Barfak(enum_Effect inOut);
uint16_t Animate_Print_Laser(enum_Effect inOut);
typedef  uint16_t (IRDN_Padidar_Zone::*animatFunction)(enum_Effect);
animatFunction animations[] = {&IRDN_Padidar_Zone::Animate_None,&IRDN_Padidar_Zone::Animate_Print,&IRDN_Padidar_Zone::Animate_Print_Random,&IRDN_Padidar_Zone::Animate_Print_Barfak,&IRDN_Padidar_Zone::Animate_Print_Laser};
};

bool IRDN_Padidar_Zone::callAnimation(enum_Effect state)
{
 uint16_t frameCounter = 0;
 frameCounter =  *animations[0](state);
 return true;
}

When I access this array in another class member function callAnimation(), I get the following error:

error: must use '.*' or '->*' to call pointer-to-member function in 'animations[0] (...)', e.g. '(... ->* animations[0]) (...)'
       frameCounter =  *animations[0](state);

If I move the typedef and array of functions to outside of the class, like this:

class IRDN_Padidar_Zone
{
bool callAnimation();  
uint16_t Animate_None(enum_Effect inOut);
uint16_t Animate_Print(enum_Effect inOut);
uint16_t Animate_Print_Random(enum_Effect inOut);
uint16_t Animate_Print_Barfak(enum_Effect inOut);
uint16_t Animate_Print_Laser(enum_Effect inOut);
};

typedef  uint16_t (IRDN_Padidar_Zone::*animatFunction)(enum_Effect);
animatFunction animations[] = {&IRDN_Padidar_Zone::Animate_None,&IRDN_Padidar_Zone::Animate_Print,&IRDN_Padidar_Zone::Animate_Print_Random,&IRDN_Padidar_Zone::Animate_Print_Barfak,&IRDN_Padidar_Zone::Animate_Print_Laser};

The error changes to:

error: too many initializers for 'uint16_t (IRDN_Padidar_Zone::* [0])(enum_Effect) {aka short unsigned int (IRDN_Padidar_Zone::* [0])(enum_Effect)}'
                                 Animate_From_Up,&IRDN_Padidar_Zone::Animate_From_Down,&IRDN_Padidar_Zone::Animate_From_UpDown,&IRDN_Padidar_Zone::Animate_Kerkerh,&IRDN_Padidar_Zone::Animate_Print_Rain};

I am confused. I am an amateur in C++. Please help me.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770

1 Answers1

3

A non-static class method needs an object to run on. Like the first error message says, you must use the .* or ->* operator when calling a non-static method via a pointer-to-method.

Also, when used as a class member, the array needs to specify how many elements it has, even though it has an inline initializer.

Try this:

class IRDN_Padidar_Zone
{
public:
    bool callAnimation(enum_Effect state);  
    uint16_t Animate_None(enum_Effect inOut);
    uint16_t Animate_Print(enum_Effect inOut);
    uint16_t Animate_Print_Random(enum_Effect inOut);
    uint16_t Animate_Print_Barfak(enum_Effect inOut);
    uint16_t Animate_Print_Laser(enum_Effect inOut);

    typedef  uint16_t (IRDN_Padidar_Zone::*animatFunction)(enum_Effect);

    animatFunction animations[5] = {&IRDN_Padidar_Zone::Animate_None, &IRDN_Padidar_Zone::Animate_Print, &IRDN_Padidar_Zone::Animate_Print_Random, &IRDN_Padidar_Zone::Animate_Print_Barfak, &IRDN_Padidar_Zone::Animate_Print_Laser};
};

bool IRDN_Padidar_Zone::callAnimation(enum_Effect state)
{
    uint16_t frameCounter = (this->*(animations[0]))(state);
    return true;
}

Online Demo

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you very much @Remy-Lebeau. My first attempt was: ` frameCounter = this->*animations[0](state);`. But you cast it and this is the right way. Another point is that if the definition of type and array is in the class, there is still error: too many initializers for 'uint16_t (IRDN_Padidar_Zone::* [0])(enum_Effect) {aka short unsigned int (IRDN_Padidar_Zone::* [0])(enum_Effect)}' Animate_From_Up,&IRDN_Padidar_Zone::Animate_From_Down,&IRDN_Padidar_Zone::Animate_From_UpDown,&IRDN_Padidar_Zone::Animate_Kerkerh,&IRDN_Padidar_Zone::Animate_Print_Rain}; – mohammad bagher Malekhosseini Aug 08 '21 at 08:20