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
。
更新:关于auto
types的一些解释:比较以下两个函数:
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
expression式来调用它们:
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
是更强大的,让你做绑定和什么。