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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9054774/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:14:51  来源:igfitidea点击:

Difference between std::function<> and a standard function pointer?

c++c++11

提问by aCuria

Whats the difference between std::function<> and a standard function pointer?

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

that is:

那是:

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

Are they effectively the same thing?

它们实际上是同一件事吗?

采纳答案by Paul Manta

A function pointer is the address of an actual function defined in C++. An std::functionis a wrapper that can hold any type of callable object (objects that can be used like functions).

函数指针是 C++ 中定义的实际函数的地址。Anstd::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);

Here, std::functionallows you to abstract away exactly what kind of callable object it is you are dealing with — you don't know it's FooFunctor, you just know that it returns voidand has one intparameter.

在这里,std::function允许您准确地抽象出您正在处理的可调用对象的类型——您不知道它是FooFunctor,您只知道它返回void并具有一个int参数。

A real-world example where this abstraction is useful is when you are using C++ together with another scripting language. You might want to design an interface that can deal with both functions defined in C++, as well as functions defined in the scripting language, in a generic way.

当您将 C++ 与另一种脚本语言一起使用时,这种抽象很有用的实际示例是。您可能希望设计一个接口,该接口可以通用方式处理 C++ 中定义的函数以及脚本语言中定义的函数。

Edit:Binding

编辑:绑定

Alongside std::function, you will also find std::bind. These two are very powerful tools when used together.

除此之外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); 

In that example, the function object returned by bindtakes the first parameter, _1, and passes it to funcas the aparameter, and sets bto be the constant 5.

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

回答by Kerrek SB

They are not the same at all. std::functionis a complex, heavy, stateful, near-magic type that can hold any sort of callable entity, while a function pointer is really just a simple pointer. If you can get away with it, you should prefer either naked function pointers or auto-bind/auto-lambda types. Only use std::functionif you really need a systematic way of organizing a heterogeneous collection of callable entities, such as functions, functors, capturing lambdas and bind expressions.

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



Update:A bit of explanation about autotypes: Compare the following two functions:

更新:关于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); }

Now imagine invoking them with a lambda or a bindexpression:

现在想象一下用 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);

The second version with the template is more efficient, because in both cases, the argument Fis deduced to the actual, unknowable type of the expression. The first version, with std::function, isn't a template and may look simpler and more deliberate, but it alwaysforces the construction of the std::functionobject, and quite possibly carries multiple type erasure and virtual dispatch costs.

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

回答by Lalaland

A std::functionhas state. It can hold additional parameters "bound" into it.

Astd::function有状态。它可以将附加参数“绑定”到其中。

These parameters can range from things like other classes, other functions, or even this pointers for member function calls.

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

The replacement function pointer is not typedef int (*fn)(int);

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

It is typedef int (*fn)(void*,int);, with the void*reperensting the state that would be hidden in the std::function.

正是typedef int (*fn)(void*,int);,随着void*再现的状态,将隐藏在std::function.

回答by Lightness Races in Orbit

No.

不。

One is a function pointer; the other is an object that serves as a wrapper around a function pointer.

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

They pretty much representthe same thing, but std::functionis farmore powerful, allowing you to do make bindings and whatnot.

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