如何声明一个接受lambda的函数?

Tho*_*ini 75 c++ lambda c++11

我在互联网上阅读了许多教程,这些教程解释了如何在标准库中使用lambdas(例如std::find),并且它们都非常有趣,但我找不到任何解释如何将lambda用于我自己的函数.

例如:

int main()
{
    int test = 5;
    LambdaTest([&](int a) { test += a; });

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

我该如何申报LambdaTest?它的第一个论点是什么类型的?然后,我如何调用传递给它的匿名函数 - 例如 - "10"作为其参数?

sep*_*p2k 70

鉴于您可能还想接受除lambdas之外的函数指针和函数对象,您可能希望使用模板来接受带有的任何参数operator().这就像find这样的std函数.它看起来像这样:

template<typename Func>
void LambdaTest(Func f) {
    f(10);
}
Run Code Online (Sandbox Code Playgroud)

请注意,此定义不使用任何c ++ 0x功能,因此它完全向后兼容.它只是使用lambda表达式调用函数,该表达式是c ++ 0x特有的.

  • 这取决于它是否是最好的.这使用模板,而另一个则不使用.这意味着该函数不再是虚拟的,不能在cpp文件中单独定义.`std :: function`完全能够获取函数对象类类型,虽然调用时稍微慢一些.但对于大多数应用来说,这种差异可以忽略不计:) (13认同)
  • 如果出现错误,则很难理解错误消息. (2认同)
  • "最好的"是旁观者的眼睛:-)这个答案使用了一个很好的"函子",但是并没有真正回答原来的问题(以及是什么导致我在这里)"我如何使用lambda为我的自己的功能".此外,模板有自己的一组问题,`std :: function`的答案没有. (2认同)
  • @Marco 这个答案不需要你使用函数,它允许你使用任何你想要的东西——包括 lambdas。 (2认同)

dou*_*lep 65

如果您不想模拟所有内容,可以执行以下操作:

void LambdaTest (const std::function <void (int)>& f)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • @Andreas Bonini:是的,如果你保存到 `std::function`(不是引用),你会复制一个 `f`。但是,当引用的对象超出范围(可能是 UB)时,我不确定 lambda/closures 如何处理引用。@FredOverflow:我的理解是 `std::function` 不是一个简单的对象,尤其是在包装 lambdas 时。最好参考它以避免不必要的复制。 (4认同)
  • 按值传递函数不是更惯用吗? (2认同)

cib*_*en1 7

我想提供这个简单但不言自明的例子.它展示了如何将"可调用事物"(函数,函数对象和lambda)传递给函数或对象.

// g++ -std=c++11 thisFile.cpp

#include <iostream>
#include <thread>

using namespace std;

// -----------------------------------------------------------------
class Box {
public:
  function<void(string)> theFunction; 
  bool funValid;

  Box () : funValid (false) { }

  void setFun (function<void(string)> f) {
    theFunction = f;
    funValid = true;
  }

  void callIt () {
    if ( ! funValid ) return;
    theFunction (" hello from Box ");
  }
}; // class

// -----------------------------------------------------------------
class FunClass {
public:
  string msg;
  FunClass (string m) :  msg (m) { }
  void operator() (string s) {
    cout << msg <<  s << endl; 
  }
};

// -----------------------------------------------------------------
void f (string s) {
  cout << s << endl;
} // ()

// -----------------------------------------------------------------
void call_it ( void (*pf) (string) ) {
  pf( "call_it: hello");
} // ()

// -----------------------------------------------------------------
void call_it1 ( function<void(string)> pf ) {
  pf( "call_it1: hello");
} // ()

// -----------------------------------------------------------------
int main() {

  int a = 1234;

  FunClass fc ( " christmas ");

  f("hello");

  call_it ( f );

  call_it1 ( f );

  // conversion ERROR: call_it ( [&] (string s) -> void { cout << s << a << endl; } );

  call_it1 ( [&] (string s) -> void { cout << s << a << endl; } );

  Box ca;

  ca.callIt ();

  ca.setFun (f);

  ca.callIt ();

  ca.setFun ( [&] (string s) -> void { cout << s << a << endl; } );

  ca.callIt ();

  ca.setFun (fc);

  ca.callIt ();

} // ()
Run Code Online (Sandbox Code Playgroud)

  • 你不需要funValid:http://en.cppreference.com/w/cpp/utility/functional/function/operator_bool,只需说`if(!theFunction)` (2认同)