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

时间:2012-01-29 16:41:06

标签: c++ c++11

std :: function<>之间的区别是什么?和标准函数指针?

即:

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

它们实际上是一回事吗?

4 个答案:

答案 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 更强大,允许你做绑定等等。