C++ 如何使用成员函数初始化'std::function'?

C++ 如何使用成员函数初始化'std::function'?,c++,c++11,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) { m

我正在努力学习
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;
}
#包括
#包括
结构Foo{
无效打印添加(int i){

std::cout
print\u add
foo
的非静态成员函数,这意味着它必须在
foo
的实例上调用;因此它有一个隐式的第一个参数,即
this
指针

使用lambda捕获
foo
实例并在其上调用
print\u add

Foo foo;
test([&foo](int i){ foo.print_add(i); });
另一个选项是使用
std::bind
绑定
foo
实例:

test(std::bind(&Foo::print_add, &foo, std::placeholders::_1));

问题

您不能直接将属于类型
Foo
的成员函数指针绑定到
std::function
,这是因为调用非静态成员函数需要类型
Foo
的实例

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

注意:但是,您可以将
&Foo::print\u添加
std::function x;
,并将其称为
x(参数的实例);

注意:还可以将其绑定到
std::function
,这需要一个
Foo*
而不是
Foo
类型的左值

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


解决方案

相反,您可以使用
std::bind
Foo
的实例绑定到相关的成员函数,如以下示例中所示:

int main(){
    Foo foo;
    test (std::bind (&Foo::print_add, foo, std::placeholders::_1));
    return 0;
}
上面我们将名为
Foo
Foo
实例绑定到成员函数指针
&Foo::print\u add


std::placeholder::_1
的使用告诉
std::bind
我们希望它生成一个可以使用一(1)个参数调用的函数对象

通过上面的代码片段,您将拥有当前所要求的行为;
my_func(5)
将相当于调用
foo.print\u add(5)


文档


你能解释一下这是如何工作的吗?也就是说,如果这是第一个参数,那么为什么它是bind中的第二个参数(…)?@Kam
bind
的第一个参数是指向成员函数的指针。之后的第二个参数是调用
std::function
时传递给该成员函数的参数。因此,指向
foo
的指针作为
print\u add
的第一个参数传递(该
指针)当您在
test
中调用callable时,
占位符::_1
意味着您稍后将提供该参数,并且您给可调用(
5
)的第一个参数将作为第二个参数传递给
print\u add
(因为占位符显示在该位置)@Kam有一个关于使用
bind
的很好的例子,并展示了如何使用移动占位符来实现不同的结果。最后一个问题:)这里哪一个是首选的?lambda还是bind?性能方面?@Kam您将两者都放在
std::function
中,并且使用其中一个占位符有一个关联,应该是关于t他和使用虚拟函数调用一样。
bind
本身不应该增加任何开销,但老实说,我不知道。我个人会在这种情况下使用lambda。第一句话不太准确,你不能将
Foo::print\u add
绑定到
std::function
,但可以将它绑定到
std::function
 std::函数
可能重复的