Search code examples
c++functionc++11function-pointers

C++ pass another method as argument


In a simple code shown below, there is a function run7 which receives a function as an argument. In main function, a function test is passed to it and it works fine. However, my method2 cannot pass the method1 to this function. It causes error:

main.cpp:24:15: error: cannot convert ‘A::method1’ from type ‘void (A::)(int)’ to type ‘void (*)(int)’
   run7(method1);
               ^

I want to call pass method1 to run7 without changing the structure of run7. How to fix method2?

#include <iostream>

using namespace std;

void run7 ( void (*f)(int) )
{
    f(7);
}

void test(int a)
{
    cout<<a<<endl;
}

class A
{
public:

    int m=4;

    void method1(int a)
    {
        cout<< a*m <<endl;
    }

    void method2()
    {
        run7(method1);
    }
};

int main()
{
    run7(test);
    return 0;
}

Solution

  • If you look at the error closely:

    error: cannot convert ‘A::method1’ from type ‘void (A::)(int)’ to type ‘void (*)(int)’

    You'll see that the types are different. That's because class methods do not have the same type as raw function - they need that extra object to get called on. There is no way to get that code to compile since calling method1 requires an A which requires storage which is impossible to pass in as a raw function pointer.

    What you can do instead is change run to take a type-erased functor:

    void run7 ( std::function<void(int)> f ) {
        f(7);
    }
    

    And then pass in a functor which also passes in this:

    void method2()
    {
        run7(std::bind(&A::method1, this,           // option 1
                       std::placeholders::_1)); 
        run7([this](int x){ this->method1(x); });   // option 2
    }