Home > Back-end >  Pass method as other method callback parameter
Pass method as other method callback parameter

Time:03-06

I'm trying to give a method as a callback of another method just like that:

Actions actions;
Button button;

int main()
{
    actions = Actions();
    button = Button();
    
    button.onClick(actions.doSmthg);

    return 0;
}

Here is my Actions:

class Actions {
  public:
    Actions();
    void doSmthg();
};

and here is the Button with my attempt of implementing a callback pattern:

class Button {
  public:
    Button() {};
    void onClick(void (*callbackPtr)());
};

Sadly I got the following error:

error: invalid use of non-static member function ‘void Actions::doSmthg()’

I've check multiple examples that suggest to use std::bind when dealing with callbacks but I'm really not sure how to make it work.

Any idea to implement such a pattern in C ?

Here is a live sandbox https://onlinegdb.com/nL3SIUOaI.

CodePudding user response:

Method 1

You can make use of std::bind and std::function as shown below:

#include <iostream>
#include <functional>
class Actions {
  public:
    Actions(){}
    void doSmthg(){
        std::cout<<"do something called"<<std::endl;
    }
};
class Button {
  public:
    Button() {};
    void setFunc(std::function<void ()> eventFunction) { fn = eventFunction; }

    void onClick(){
        std::cout<<"button clicked"<<std::endl;
        //call the function on the passed object
        fn();
        
    }
    private:
     std::function<void ()> fn;
};

int main()
{
    Actions action;
    Button button;
    button.setFunc(std::bind(&Actions::doSmthg, action));
    
    button.onClick();

    return 0;
}

The output of the above program can be seen here:

button clicked
do something called

Method 2

Here we make the onClick member function to be a member function template.

#include <iostream>

class Actions {
  public:
    Actions(){}
    void doSmthg(){
        std::cout<<"do something called"<<std::endl;
    }
};
class Button {
  public:
    Button() {};
    template<typename T>
    void onClick(void (T::*callbackPtr)(), T obj){
        std::cout<<"button clicked"<<std::endl;
        //call the function on the passed object
        (obj.*callbackPtr)();
    }
};
int main()
{
    Actions action;
    Button button;;
    
    button.onClick<Actions>(&Actions::doSmthg, action);

    return 0;
}

The output of the above program can be seen here:

button clicked
do something called
  • Related