如何使用成员函数初始化`std :: function`?

Kam*_*Kam 2 c++ c++11

我正在努力学习std::function,这是我的代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

编译器错误:

 error: cannot convert 'Foo::print_add' from type 'void (Foo::)(int)' to type 'fp {aka std::function<void(int)>}'
     test(foo.print_add);
Run Code Online (Sandbox Code Playgroud)

如何使这项工作,即如何将成员函数作为参数传递?

Pra*_*ian 9

print_add是一个非静态成员函数foo,这意味着它必须在一个实例上调用Foo; 因此它有一个隐含的第一个参数,this指针.

使用捕获foo实例并print_add在其上调用的lambda .

Foo foo;
test([&foo](int i){ foo.print_add(i); });
Run Code Online (Sandbox Code Playgroud)

另一个选项是用于std::bind绑定foo实例:

test(std::bind(&Foo::print_add, &foo, std::placeholders::_1));
Run Code Online (Sandbox Code Playgroud)

现场演示


for*_*818 9

您需要一个对象来调用非静态成员函数。因此,当您想获得 a 时,std::function您有多种选择:

  • 使方法静态
  • std::function通过 lambda将对象绑定到
  • 将对象绑定到std::functionvia 自定义函子
  • std::function调用时传递对象

#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";
    
}
Run Code Online (Sandbox Code Playgroud)