2

I'm trying to find a way to provide pointers to a member functions between different class instances. For the moment I'm able to provide pointers to member function that takes no arguments but cannot manage to do so when the function to point to has an argument.

A sample code to illustrate my problem :

#include <iostream>

class Event
{
public:
    std::string type;
    Event(std::string type):type(type){}
};

class EventDispatcherBase
{
public:

    void addEventListener(std::function<void(Event &event)> listener)
    {
        Event myEvent("Type of the myEvent object");
        listener(myEvent);
    }
};

class EventDispatcherClass:public EventDispatcherBase
{
public:
    EventDispatcherClass()
    {
        addEventListener([](Event &event){std::cout << event.type << std::endl;});
        //addEventListener([this]{listener(Event event);});
    };

    void listener(Event &event)
    {
        std::cout << event.type << std::endl;
    }
};

int main()
{
    EventDispatcherClass eventDispatcherClass;

    return 0;
}

This code works with an anonymous lambda expression and output "Type of the myEvent object" in the console. But if I uncomment the line

addEventListener([this]{listener(Event event);});

in the constructor of the EventDispatcherClass in order to transmit a pointer to the void listener(Event &event) member function, the compiler throw the following error :

no viable conversion from '(lambda at .../main.cpp:27:26)' to 'std::function'

I don't understand why.

1
  • 1
    There are no pointers to member functions here. Commented May 28, 2019 at 10:04

3 Answers 3

4

but cannot manage to do so when the function to point to has an argument.

The lambda should take an argument of type Event&, which will be forwarded to the member function inside the lambda. So change it to

addEventListener([this](Event &event){listener(event);});
//                     ^^^^^^^^^^^^^^

LIVE

Sign up to request clarification or add additional context in comments.

Comments

3

The working line:

addEventListener([](Event &event){std::cout << event.type << std::endl;});

looks nothing like the broken one:

//addEventListener([this]{listener(Event event);});

so start by changing the working line bit by bit.

  1. add the capture expression you will want, and it still works

    addEventListener([this](Event &event){std::cout << event.type << std::endl;});
    
  2. change the body to the one you want, and it still works

    addEventListener([this](Event &event){ this->listener(event); });
    

If you're having trouble seeing what's different between the two versions - which is actually pretty common when you wrote them yourself and you're seeing what you intended to type instead of what's there - try changing the layout to line everything up (so you'd see the missing (Event &event)), or transforming one into the other step-by-step as above, or just replace one with the other and diff the file versions.

1 Comment

Thank you very much for the clear explanation. It works fine now.
0

just change it to addEventListener(listener);

and make the function itself static as static void listener(Event &event)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.