std :: function的用法和语法

时间:2013-12-03 14:02:07

标签: c++ c++11 function-pointers std-function

我有必要使用std::function,但我不知道std::function<void()> f_name = []() { FNAME(); };语法是什么意思。

使用std :: function的目标是什么?它是否指向函数?

2 个答案:

答案 0 :(得分:31)

std::function是类型擦除对象。这意味着它会删除某些操作发生的细节,并为它们提供统一的运行时接口。对于std::function,操作是复制/移动和operator()的'调用' - '函数类似于调用操作符'。

在较少深奥的英语中,这意味着std::function几乎可以包含任何对象,就像你调用它时的函数指针一样。

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

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

该行的下一部分是lambda。这是C ++ 11中的新语法,用于添加编写简单函数类对象的功能 - 可以使用()调用的对象。这些对象可以被类型擦除并存储在std::function中,代价是一些运行时开销。

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

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

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

完整的lambda语法如下:

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

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

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

基本上变成了

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
  }
};

答案 1 :(得分:17)

让我们分开界限:

的std ::功能

这是一个不带参数的函数的声明,并且不返回任何值。如果函数返回int,它将如下所示:

std::function<int()>

同样,如果它也采用了int参数:

std::function<int(int)>

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

[]() { FNAME(); };

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

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

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

其余部分是lambda本身的主体,好像它是一个常规函数,我们只能调用函数FNAME

另一个例子

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

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

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

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

不确定您是否正在使用MSVC,但这里是lamda表达式语法的链接:

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