Search code examples
c++esp32arduino-c++arduino-esp32

Get result from array of member functions in c++


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.


Solution

  • 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