C++ std::function 的用法和语法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20353210/
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 23:04:38  来源:igfitidea点击:

Usage and Syntax of std::function

c++function-pointersstd-function

提问by user2982229

It is necessary to me to use std::functionbut I don't know what the following syntax means.

我有必要使用,std::function但我不知道以下语法是什么意思。

std::function<void()> f_name = []() { FNAME(); };

What is the goal of using std::function? Is it to make a pointer to a function?

使用的目的是std::function什么?是要创建一个指向函数的指针吗?

回答by Yakk - Adam Nevraumont

std::functionis a type erasure object. That means it erases the details of how some operations happen, and provides a uniform run time interface to them. For std::function, the primary1operations are copy/move, destruction, and 'invocation' with operator()-- the 'function like call operator'.

std::function是一个类型擦除对象。这意味着它删除了某些操作如何发生的细节,并为它们提供了统一的运行时接口。对于std::function,主要的1操作是复制/移动、销毁和“调用” operator()——“调用运算符之类的函数”。

In less abstruse English, it means that std::functioncan contain almost any object that acts like a function pointer in how you call it.

在不那么深奥的英语中,这意味着它std::function可以包含几乎任何在您调用它时充当函数指针的对象。

The signature it supports goes inside the angle brackets: std::function<void()>takes zero arguments and returns nothing. std::function< double( int, int ) >takes two intarguments and returns double. In general, std::functionsupports storing any function-like object whose arguments can be converted-from its argument list, and whose return value can be converted-to its return value.

它支持的签名位于尖括号内:std::function<void()>接受零个参数并且不返回任何内容。 std::function< double( int, int ) >接受两个int参数并返回double. 通常,std::function支持存储任何类似函数的对象,其参数可以从其参数列表转换,并且其返回值可以转换为它的返回值。

It is important to know that std::functionand lambdas are different, if compatible, beasts.

重要的是要知道std::function和 lambdas 是不同的,如果兼容,野兽。

The next part of the line is a lambda. This is new syntax in C++11 to add the ability to write simple function-like objects -- objects that can be invoked with (). Such objects can be type erased and stored in a std::functionat the cost of some run time overhead.

该行的下一部分是一个 lambda。这是 C++11 中的新语法,增加了编写简单的类函数对象的能力——可以用(). 这样的对象可以被类型擦除并存储在 a 中std::function,但会产生一些运行时开销。

[](){ code }in particular is a really simple lambda. It corresponds to this:

[](){ code }特别是一个非常简单的 lambda。它对应于:

struct some_anonymous_type {
  some_anonymous_type() {}
  void operator()const{
    code
  }
};

an instance of the above simple pseudo-function type. An actual class like the above is "invented" by the compiler, with an implementation defined unique name (often including symbols that no user-defined type can contain) (I do not know if it is possible that you can follow the standard without inventing such a class, but every compiler I know of actually creates the class).

上述简单伪函数类型的实例。像上面这样的实际类是由编译器“发明”的,具有实现定义的唯一名称(通常包括用户定义类型不能包含的符号)(我不知道您是否可以在不发明的情况下遵循标准这样一个类,但我知道的每个编译器实际上都创建了这个类)。

The full lambda syntax looks like:

完整的 lambda 语法如下所示:

[ capture_list ]( argument_list )
-> return_type optional_mutable
{
  code
}

but many parts can be omitted or left empty. The capture_list corresponds to both the constructor of the resulting anonymous type and its member variables, the argument_list the arguments of the operator(), and the return type the return type. The lambda instance's constructor is also magically called when the instance is created with the capture_list.

但许多部分可以省略或留空。capture_list 对应于生成的匿名类型的构造函数及其成员变量,argument_list 对应于 的参数,operator()返回类型对应于返回类型。使用 capture_list 创建实例时,也会神奇地调用 lambda 实例的构造函数。

[ capture_list ]( argument_list ) -> return_type { code }

basically becomes

基本上变成

struct some_anonymous_type {
  // capture_list turned into member variables
  some_anonymous_type( /* capture_list turned into arguments */ ):
    /* member variables initialized */
  {}
  return_type operator()( argument_list ) const {
    code
  }
};


1In addition, RTTI is stored (typeid), and the cast-back-to-original-type operation is included.

1另外,存储RTTI(typeid),包括cast-back-to-original-type操作。

回答by Moo-Juice

Let's break the line apart:

让我们把这条线分开:

std::function

标准::函数

This is a declaration for a function taking no parameters, and returning no value. If the function returned an int, it would look like this:

这是对不带参数且不返回值的函数的声明。如果函数返回一个int,它看起来像这样:

std::function<int()>

Likewise, if it took an int parameter as well:

同样,如果它也接受一个 int 参数:

std::function<int(int)>

I suspect your main confusion is the next part.

我怀疑你的主要困惑是下一部分。

[]() { FNAME(); };

The []part is called a capture clause. Here you put variables that are local to the declaration of your lambda, and that you want to be available withinthe lambda function itself. This is saying "I don't want anything to be captured". If this was within a class definition and you wanted the class to be available to the lambda, you might do:

[]部分称为捕获子句。在这里,您放置了 lambda 声明的局部变量,并且您希望lambda 函数本身中可用。这就是说“我不希望任何东西被捕获”。如果这是在类定义中,并且您希望该类可用于 lambda,则可以执行以下操作:

[this]() { FNAME(); };

The next part, is the parameters being passed to the lambda, exactly the same as if it was a regular function. As mentioned earlier, std::function<void()>is a signature pointing to a method that takes no parameters, so this is empty also.

下一部分是传递给 lambda 的参数,与常规函数完全相同。如前所述,std::function<void()>是指向不带参数的方法的签名,因此它也是空的。

The rest of it is the body of the lambda itself, as if it was a regular function, which we can see just calls the function FNAME.

其余部分是 lambda 本身的主体,就好像它是一个常规函数,我们可以看到它只是调用了 function FNAME

Another Example

另一个例子

Let's say you had the following signature, that is for something that can sum two numbers.

假设您有以下签名,即可以将两个数字相加的东西。

std::function<int(int, int)> sumFunc;

We could now declare a lambda thusly:

我们现在可以这样声明一个 lambda:

sumFunc = [](int a, int b) { return a + b; };

Not sure if you're using MSVC, but here's a link anyway to the lamda expression syntax:

不确定您是否使用 MSVC,但这里有一个指向 lamda 表达式语法的链接:

http://msdn.microsoft.com/en-us/library/dd293603.aspx

http://msdn.microsoft.com/en-us/library/dd293603.aspx