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

aCu*_*ria 56 c++ c++11

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

那是:

typedef std::function<int(int)> FUNCTION;
typedef int (*fn)(int);
Run Code Online (Sandbox Code Playgroud)

它们实际上是一回事吗?

Ker*_* SB 45

它们完全不一样.std::function是一个复杂,沉重,有状态,近乎魔法的类型,可以容纳任何类型的可调用实体,而函数指针实际上只是一个简单的指针.如果你能逃脱它,你应该更喜欢裸函数指针或auto- bind/ auto-lambda类型.只有std::function在你真的需要一种系统的方法来组织异构的可调用实体集合时才使用,例如函数,仿函数,捕获lambdas和绑定表达式.


更新:关于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); }
Run Code Online (Sandbox Code Playgroud)

现在想象一下用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);
Run Code Online (Sandbox Code Playgroud)

带有模板的第二个版本更有效,因为在这两种情况下,参数都F被推导为表达式的实际不可知类型.第一个版本,std::function不是模板,可能看起来更简单,更有意思,但它总是强制std::function对象的构造,并且很可能带有多种类型的擦除和虚拟调度成本.

  • @aCuria:如果你想制作一个可调用的东西容器,你想把各种混合类型放在那里,那么你*有*使用`std :: function`并转换所有内容.但是如果你知道你总是拥有真正的自由函数,那么你就可以创建一个函数指针容器.我将稍微扩展实际帖子中的自动首选项. (4认同)
  • 函数指针不适用于**lambdas捕获上下文变量**.如果你期望使用lambdas,那么`std :: function`是更好的选择. (4认同)

Pau*_*nta 43

函数指针是C++中定义的实际函数的地址.An 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);
Run Code Online (Sandbox Code Playgroud)

在这里,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); 
Run Code Online (Sandbox Code Playgroud)

在该示例中,返回的函数对象bind获取第一个参数,_1并将其func作为a参数传递给它,并设置b为常量5.

  • 什么是_1在这里? (3认同)

Lal*_*and 11

A std::function有州.它可以将其他参数"绑定"到其中.

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

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

这是typedef int (*fn)(void*,int);一个void*重复的国家,将隐藏在国家std::function.


Lig*_*ica 8

不。

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

它们几乎代表了同样的事情,但是std::function远远更为强大,让你做化妆绑定和诸如此类的东西。

  • -1 不是因为它不正确,而是不精确和不清楚。首先,你应该解释一下 `std::function` 是一个可调用对象的包装器(例如函数指针,但不仅限于此)。此外,`std::function` 只是一个包装器,您不会专门使用它来进行绑定。 (14认同)
  • -1:同意保罗。这个答案需要更多细节。 (7认同)
  • ...这不是转换。 (3认同)