Search code examples
c++std-function

Passing a callback function pointer to a function in another class


I know questions like this have been asked, but none of the answers have helped me. Although I have coded some C++ in the past as needed I am not fluent by any stretch. Today, I am stuck trying to pass a callback function to a function in another class. Below is a short example:

#include "stdafx.h"
#include <functional>

class A
{
private:
    int _someMemberVar = 7;

public:
    void SomeFunction(std::function<void(int)> func)
    {
        func(_someMemberVar);
    }
};

class B
{
public:
    void DoSomeWork()
    {
        A a;

        // error C2275: 'std::function<void (int)>' : illegal use of this type as an expression
        a.SomeFunction(std::function<void(int)> &B::MyCallback);
    }

    void MyCallback(int i)
    {
        printf("parameter is %d\r\n", i);
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    B b;
    b.DoSomeWork();

    return 0;
}

I have tried the example code from this std::function documentation page, but it doesn't compile. I had similar issues with other examples I found, such as those in the dissertation here. I am using Visual Studio 2013.

Googling the various compiler errors hasn't helped me sort this out and I'm feeling frustrated and confused. About the only thing I know for sure is that we C# programmers sure are spoiled. Any help is greatly appreciated.


Edit: Thanks so much for all the help everyone. All the answers provided a working solution, and if I could green check them all I would. I went with the answer posted by super because it had the most explanation and seems closest to what I am porting. Thanks again all!


Solution

  • Apart from the missing brackets around &B::MyCallback (typo?) the main issue here is that a member function and a normal function are not the same thing.

    A member function acts on an object, while a function does not, so a pointer to a member function can't just be converted to a normal function pointer.

    The most straight forward solution in your case is to pass a lambda that captures this.

    a.SomeFunction([&](int i){ MyCallback(i); });
    

    The lambda will capture the current object and forward i as a parameter to the member function.