I am trying to learn std::function and here's my code:
#include <iostream>
#include <functional>
struct Foo {
    void print_add(int i){ 
      std::cout << i << '\n'; 
    }
};
typedef std::function<void(int)> fp;
void test(fp my_func)
{
  my_func(5);
}
int main(){
    Foo foo;
    test(foo.print_add);
    return 0;
}
Compiler Error:
 error: cannot convert 'Foo::print_add' from type 'void (Foo::)(int)' to type 'fp {aka std::function<void(int)>}'
     test(foo.print_add);
How can I make this work, i.e how can I pass a member function as a parameter?
print_add is a non-static member function of foo, which means it must be invoked on an instance of Foo; hence it has an implicit first argument, the this pointer.
Use a lambda that captures the foo instance and invokes print_add on it.
Foo foo;
test([&foo](int i){ foo.print_add(i); });
Another option is to use std::bind to bind the foo instance:
test(std::bind(&Foo::print_add, &foo, std::placeholders::_1));
Live demo
You need an object to call a non-static member function. Hence, when you want to get a std::function you have several options:
std::function
std::function is called#include <iostream>
#include <functional>
struct A {
    int i = 42;
    int get() const { return i; }    
    
    static int get_static() { return 0; }
};
struct A_functor {
    A a;    
    int operator()() const { return a.get(); }
};
int main() {    
    // static method
    std::function<int()> f1 = &A::get_static;
    std::cout << f1() << "\n";
    // bind an object to the function via lambda
    A a;
    std::function<int()> f2 = [&a](){ return a.get(); };
    std::cout << f2() << "\n";
    // store the object in the std::function
    std::function<int()> f3 = A_functor{};
    std::cout << f3() << "\n";
    // or 
    std::function<int()> f4 = [a = A()](){ return a.get(); };
    std::cout << f4() << "\n";
    // pass the object when the std::function is called
    std::function<int(A&)> f5 = &A::get;
    std::cout << f5(a) << "\n";
    // or 
    std::function<int(A*)> f6 = &A::get;
    std::cout << f6(&a) << "\n";
    
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With