传递带参数的lambda函数

4

I would like to pass a lambda to a funciton.

This

boost::function<void()> fncPtr(boost::bind<void>([](){/* something */}));

这个代码可以运行,但如果lambda有参数,我不知道如何正确处理:

boost::function<void(bool)>
fncPtr(boost::bind<void,bool>([](bool){/* something */}, _1));

不起作用。

我错在哪里? 如何传递带参数的lambda表达式?

我想在成员函数中这样做。 所以在“全局范围”(是这个名称吗?)上述方法可以正常工作。


函数的参数是什么? - Xeo
嗯,我也想不出为什么这个不起作用。(当然,在所提供的微不足道的情况下,没有必要在 lambda 中使用 bind;但这并不是重点。) - Lightness Races in Orbit
3个回答

3

使用GCC4.5对我来说运行正常:

#include <boost/bind.hpp>
#include <boost/function.hpp>

int main() {
  boost::function<void(bool)>
    fncPtr(boost::bind<void>([](bool){/* something */}, _1));
}

它不需要参数类型。对于某些functors,这些参数类型可以是模板的,因此通常不能依赖于它们。它只需要返回类型。
顺便说一下,当我传递<void,bool>时,即使lambda没有捕获,它也能为我工作。我认为这可能对我起作用,因为GCC4.5支持将lambda转换为函数指针类型,当lambda没有捕获子句时。 <void,bool>将使bind具有接受函数指针的候选项,并使lambda转换为该候选项。您的编译器显然尚不支持该特殊转换(但FDIS要求它)。
所以,只需传递<void>,它就可以工作了。

2

我在这里的Ideone总结了一些技巧。请注意,我使用的是C++0x版本,Boost版本也应该可以正常工作。
但实际上,这取决于您的函数需要什么参数。如果它只是模板化的或者接受一个(std::|boost::)function,那么一个简单的lambda表达式就足够了。不需要复杂的绑定或将其打包到额外的(std::|boost::)function中。


1
我认为C++0x版本不需要额外的<void>,因为它的bind声明返回类型为result_of<BindType(ArgTypes...)>::type(或类似的内容)。boost没有像decltype这样用于推断返回类型的闪亮功能,所以它依赖于函数对象提供的result_type typedef,而lambda表达式不提供。 - Johannes Schaub - litb
@Johannes:谢谢,很有趣知道lambda不提供这些。为什么呢?只是因为C++0x中由于decltype而不再需要它了吗? - Xeo

0

你可能在编译器中遇到了问题。我在Visual Studio 2010中也遇到了错误。你可以使用辅助函数帮助编译器将lambda转换为函数:

template <typename T>
void closureToFunction(bool x){ T f; return f(x); }

int main()
{
    auto exp = [](bool x){/* something */};
    boost::function<void(bool)> fncPtr( 
      boost::bind( closureToFunction<decltype(exp)>, _1) );
    return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接