C ++ Lambda-如何捕获函数参数

时间:2019-12-27 18:54:48

标签: c++ lambda

我有一个函数(fn1),该函数接收另一个函数(fn2)作为参数。我希望从lambda内部执行该参数,该参数将作为参数传递给另一个函数(fn3)。像这样:

void fn1(void (*fn2)()) {
  // execute fn2 parameter inside lambda
  fn3([ fn2 ] () { fn2(); });
}

void fn3(void (*lambda)()) {
  // do stuff ...
  lambda();
}

如果我尝试对此进行编译,则会出现以下错误:
无法将参数'fn3(void (*)())::'转换为'void (*)()'的{​​{1}}到'1'

如果我只是在lambda中执行函数(不带fn3),则可以正常编译。

'void fn1(void (*)())'

我在做什么错了?

2 个答案:

答案 0 :(得分:4)

捕获的Lambda具有状态,因此它们与自由函数有根本的区别,您不能在两者之间进行强制转换。

代替使用函数指针,您可以将函数更改为接受任何可调用的函数:

void foo(){}

template <typename T>
void fn3(T t) {
  // do stuff ...
  t();
}

void fn1(void (*fn2)()) {
  // execute fn2 parameter inside lambda
  fn3([ fn2 ] () { fn2(); });
}

int main() {
   fn1(foo); 
}

我只修改了fn3,但我建议对fn1进行同样的修改。

答案 1 :(得分:3)

带有捕获的Lambda也不转换为函数指针。

代替使用std :: function之类的

#include <iostream>
#include <functional>

void fn3( const std::function<void()> &lambda ) 
{
  lambda();
}

void fn1(void (*fn2)()) 
{
  fn3( std::function<void()>( [ fn2 ] () { fn2(); } ) );
}


void fn2() { std::cout << "Hello World!\n"; }

int main() 
{
    fn1( fn2 );
    return 0;
}

程序输出为

Hello World!