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::coutprint\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中的第二个参数(…)?@Kambind
的第一个参数是指向成员函数的指针。之后的第二个参数是调用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::函数
可能重复的