传递lambda与捕获作为另一个lambda的参数,可能吗?

时间:2016-06-16 13:44:17

标签: c++ lambda

是否可以将带有捕获的lambda函数作为另一个lambda函数的参数传递?

int a=3;
auto func_1=[&]()->{a=4;};
auto func_2=[&](  ?????  fParam   ){  fParam(); }; //what is a proper ?????
func_2(func_1);

(我想用它来做一些奇特的事情。)

修改

感谢许多解决方案。我学到了很多东西。

在原始问题中,我忘了提及 func_2 也希望接收其他功能,例如 func_2(func_1a) func_2(func_1b)等。

因此, decltype 是原始问题的正确答案之一,但不符合我的要求。

3 个答案:

答案 0 :(得分:7)

这就是auto的用途:

auto func_2=[&](auto fParam   ){  fParam(); }; 

您的编译器必须至少具有C ++ 14级语言支持。

编辑:使用C ++ 11,以下似乎可行:

auto func_2=[&](decltype(func_1)  fParam   ){  fParam(); }; 

答案 1 :(得分:3)

正如克里斯在评论中所说,你可以使用std::function。鉴于您对auto固有缺乏类型检查的担忧,这样做的好处是它允许您限制特定签名的可调用对象,因为std::function是一个为每个签名实例化一次的模板在您的程序中,模板实例化不可转换。它可以毫不费力地保存lambda,就像任何其他可调用对象一样。

这种级别的类型检查可能比decltype(oneSpecificLambda)版本更有用,但这对于了解有用!

将此与其他答案相结合,您可以选择在声明点限制传递的参数,至少有3种方式:

  • 根本不是= auto
  • 到特定的函数签名= std::function< T_Return(T_Args...) >
  • 或特定的单个函数对象= decltype(oneSpecificLambda),因为每个lambda都是一个不同的未命名类型,同样不能转换。

就个人而言,我可能只会在这种情况下使用auto并相信自己不会意外传递任何其他内容。但是有这么多的选择很好!

答案 2 :(得分:1)

我很确定这也会奏效,但正如Sam Varshavchik所说,如果C ++ 14可用,那么只需使用auto。

int a=3;
auto func_1=[&]()->{a=4;};
auto func_2=[&](  decltype(func_1) fParam ){  fParam(); };
func_2(func_1);