How to initialize `std::function` with a member-function?

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


THE PROBLEM

You cannot directly bind a member-function pointer belonging to type Foo to std::function<void(int)>, specifically because calling a non-static member-function requires an instance of type Foo.

Foo obj; obj.member_function (); // can't call `member_function` without `obj`

Note: You can however bind &Foo::print_add to std::function<void(Foo&, int)> x;, and call it as x(instance_of_Foo, arg);.

Note: It's also possible to bind it to std::function<void(Foo*, int>, which would require a Foo* instead of an lvalue of type Foo.



THE SOLUTION

Instead you can use std::bind to bind an instance of Foo to the member-function in question, such as in the below example:

int main(){
    Foo foo;
    test (std::bind (&Foo::print_add, foo, std::placeholders::_1));
    return 0;
}

Above we bind an instance of Foo named foo to the member-function pointer &Foo::print_add.


The usage of std::placeholders::_1 tells std::bind that we'd like it to generate a function-object that is callable using one (1) argument.

With the above snippet you will have the behaviour that you are currently asking for; my_func(5) will be equivalent of calling foo.print_add (5).


DOCUMENTATION

  • std::function - cppreference.com
  • std::bind - cppreference.com
  • std::placeholders - cppreference.com