std :: function <>和一个标准函数指针之间的区别?

std :: function <>和一个标准函数指针有什么区别?

那是:

typedef std::function<int(int)> FUNCTION; typedef int (*fn)(int); 

他们实际上是一样的东西吗?

函数指针是在C ++中定义的实际函数的地址。 std::function是一个包装器,可以容纳任何types的可调用对象(可以像函数一样使用的对象)。

 struct FooFunctor { void operator()(int i) { std::cout << i; } }; // Since `FooFunctor` defines `operator()`, it can be used as a function FooFunctor func; std::function<void (int)> f(func); 

在这里, std::function允许你抽象出你正在处理的是什么types的可调用对象 – 你不知道它是FooFunctor ,你只知道它返回的是void并且有一个int参数。

这个抽象是有用的一个真实世界的例子是当你将C ++与另一种脚本语言一起使用时。 您可能希望devise一个接口,以通用的方式处理C ++中定义的函数以及脚本语言中定义的函数。

编辑: 绑定

除了std::function ,你还会发现std::bind 。 这两个是一起使用时非常强大的工具。

 void func(int a, int b) { // Do something important } // Consider the case when you want one of the parameters of `func` to be fixed // You can used `std::bind` to set a fixed value for a parameter; `bind` will // return a function-like object that you can place inside of `std::function`. std::function<void (int)> f = std::bind(func, _1, 5); 

在这个例子中, bind返回的函数对象取第一个参数_1 ,并将其作为parameter passing给func ,并将b设置为常量5

他们根本不一样。 std::function是一个复杂的,沉重的,有状态的,接近魔术的types,可以容纳任何types的可调用实体,而函数指针实际上只是一个简单的指针。 如果你能摆脱它,你应该更喜欢裸函数指针或auto bind / auto -lambdatypes。 如果你真的需要一个系统的方式来组织一个可调用的实体集合,比如函数,函数,捕获lambdaexpression式和绑定expression式,那么只能使用std::function


更新:关于autotypes的一些解释:比较以下两个函数:

 void do_something_1(std::function<void(int)> f, int a) { f(a); } template <typename F, typename A> void do_something_2(F f, A a) { f(a); } 

现在想象用lambda或bindexpression式来调用它们:

 do_something_X([foo, &bar](int n){ bar += n*foo; }, 12); do_something_X(std::bind(X::bob, &jim, true, _1, Blue), 13); 

带模板的第二个版本更有效率,因为在这两种情况下,参数F被推导为实际的,不可知的expression式types。 使用std::function的第一个版本不是一个模板,看起来可能更简单,更审慎,但是它总是强制构造std::function对象,而且很可能会带有多种types的擦除和虚拟调度成本。

一个std::function有状态。 它可以容纳额外的参数“绑定”到其中。

这些参数的范围可以从其他类,其他函数,甚至成员函数调用的指针。

replace函数指针不是typedef int (*fn)(int);

它是typedef int (*fn)(void*,int); ,用void*表示将隐藏在std::function

没有。

一个是函数指针; 另一个是用作函数指针的包装的对象。

他们几乎代表了同样的事情,但std::function是更强大的,让你做绑定和什么。