std :: function<>之间的区别是什么?和标准函数指针?
即:
typedef std::function<int(int)> FUNCTION;
typedef int (*fn)(int);
它们实际上是一回事吗?
答案 0 :(得分:44)
它们完全不一样。 std::function
是一个复杂,沉重,有状态,近乎魔法的类型,可以容纳任何类型的可调用实体,而函数指针实际上只是一个简单的指针。如果你能逃脱它,你应该更喜欢裸函数指针或auto
- bind
/ auto
- lambda类型。如果你真的需要一种系统的方法来组织异构的可调用实体集合,例如函数,函子,捕获lambdas和绑定表达式,那么只能使用std::function
。
更新:关于auto
类型的一些解释:比较以下两个函数:
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或bind
表达式调用它们:
do_something_X([foo, &bar](int n){ bar += n*foo; }, 12);
do_something_X(std::bind(X::bob, &jim, true, _1, Blue), 13);
使用模板的第二个版本更有效,因为在这两种情况下,参数F
都被推导为表达式的实际不可知类型。带std::function
的第一个版本不是模板,可能看起来更简单,更有意思,但始终强制构造std::function
对象,并且很可能带有多类型擦除和虚拟调度成本。
答案 1 :(得分:42)
函数指针是C ++中定义的实际函数的地址。 std::function
是一个包装器,可以容纳任何类型的可调用对象(可以像函数一样使用的对象)。
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
允许你抽象出你正在处理的是什么类型的可调用对象 - 你不知道它是FooFunctor
,你只知道它返回void
并且有一个int
参数。
这种抽象很有用的现实示例是当您将C ++与其他脚本语言一起使用时。您可能希望设计一个接口,该接口可以通用方式处理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
,并将其作为func
参数传递给a
,并设置{{ 1}}是常量b
。
答案 2 :(得分:11)
std::function
有州。它可以将其他参数“绑定”到其中。
这些参数的范围可以是其他类,其他函数,甚至是成员函数调用的指针。
替换函数指针不是typedef int (*fn)(int);
typedef int (*fn)(void*,int);
,void*
重新启用隐藏在std::function
中的州。
答案 3 :(得分:4)
没有
一个是函数指针;另一个是一个对象,用作函数指针的包装器。
他们几乎代表同样的事情,但std::function
远更强大,允许你做绑定等等。