4

I would like to pass a lambda to a funciton.

This

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

works, but if the lambda had a parameter, I don't know how to do it properly:

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

does not work.

Where I am wrong? How to pass lambda with argument(s)?

I would like to do this in a member function. So in "global scope"(is it the name?) this method above works fine.

2
  • What are the function's parameters? Commented Apr 22, 2011 at 13:31
  • Hmm yea I can't figure out why this doesn't work, either. (Of course, in the trivial case presented, there's no need to wrap the lambda in bind; but that's hardly the point.) Commented Apr 22, 2011 at 13:59

3 Answers 3

3

This works fine for me with GCC4.5:

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

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

It doesn't need the type of the parameters. Those parameter types could be templated anyway (for some functors), so in general it cannot depend on them. It only needs the return type.

Incidentally, it even works for me when I pass <void, bool>, but only when the lambdas has no captures. I think that this may work for me because GCC4.5 supports conversion of lambdas to function pointer types, when the lambdas has no capture clause. <void, bool> would make bind have a candidate that accepts a function pointer, and make the lambda convert to that. Your compiler apparently doesn't support that special conversion yet (but the FDIS requires it).

So, just pass <void> only, and it should work.

Sign up to request clarification or add additional context in comments.

Comments

2

I summed up some techniques here on Ideone. Note, I used the C++0x versions, the Boost ones should work just fine too.
It really depends though on what your function wants as a parameter though. If it is simply templated or takes a (std::|boost::)function, then a simple lambda will do. No need for complicated binding or packaging in an extra (std::|boost::)function.

2 Comments

I think the C++0x versions don't need the extra <void>, because its bind declares the return type as result_of<BindType(ArgTypes...)>::type (or something similar). boost doesn't have all the shiny things like decltype for deducing the return type, so it depends on a result_type typedef being provided by the functor, which lambdas don't provide.
@Johannes: Thanks, it's interesting to know that lambdas don't provide those. Any rationale on why? Just because you don't need it anymore for C++0x because of decltype?
0

You have a problem in the compiler probably. I have an error in Visual Studio 2010 too. You can help compiler to convert a lambda to a function using helper function:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.