0

I want to create a custom event handler into a class and pass function of another class.

class EventArgs
{

};

class one
{
public:
    typedef void(EventHandler)(EventArgs* e);
    void RegisterFunction(EventHandler* f);

private:
    list<EventHandler*>function_list;
};

class two
{
public:
    two();
private:
    void FunctionEvent(EventArgs* e);
};

two::two()
{
    one on;
    on.RegisterFunction(&FunctionEvent);
}

The error code is: no matching function for call to ‘one::RegisterFunction(void (two::) EventArgs))’ on.RegisterFunction(&FunctionEvent);

if the FunctionEvent() it does not belong at class two like this work:

void FunctionEvent(EventArgs* e)
{

}

int main()
{
    one on;
    on.RegisterFunction(&FunctionEvent);
}

what is the difference?

  • 2
    Possible duplicate of [How can I pass a member function where a free function is expected?](https://stackoverflow.com/questions/12662891/how-can-i-pass-a-member-function-where-a-free-function-is-expected) – G.M. Jun 03 '19 at 21:19

1 Answers1

0

The simplest and most generic way to make this work for all cases would be to use std::function. It's really easy to use, and it works just like a regular function. In addition, std::function works with lambads, function pointers, and when used with std::bind, it can even be used with member functions.

For your particular case, we'll want to make EventHandler a function that accepts EventArgs* and returns nothing:

using EventHandler = std::function<void(EventArgs*)>;

It's really easy to create it from a lambda or a function pointer:

// Create it from a lambda
EventHandler x = [](EventArgs* args) { /* do stuff */ };

void onEvent(EventArgs* args) {}

EventHandler y = &onEvent; // Create it from function pointer

In addition, you can use std::bind to create it from a member function:

// Create it from a member function
struct MyHandler {
    void handleEvent(EventArgs* args); 
};

MyHandler handler; 
EventHandler z = std::bind(&MyHandler::handleEvent, handler); 

Rewriting your classes

class one
{
public:
    // Use std::function instead of function pointer
    using EventHandler = std::function<void(EventArgs*)>; 

    // Take the function by value, not by pointer. 
    void RegisterFunction(EventHandler f);

private:
    // Store the function by value, not pointer
    list<EventHandler>function_list;
};
class two
{
public:
    two();
private:
    void FunctionEvent(EventArgs* e);
};

two::two()
{
    one on;
    on.RegisterFunction(std::bind(&two::FunctionEvent, this));
}
Alecto Irene Perez
  • 10,321
  • 23
  • 46