[boost-users][lambda] calling a functor in-place

Hi, std::vector<boost::function<void(void)> > functors; using namespace boost::lambda; std::for_each (functors.begin(), functor.end(), _1); The above compiles, but...does nothing. How can I enforce calling of operator () ? Thank you in advance!

Igor R wrote:
std::vector<boost::function<void(void)> > functors; using namespace boost::lambda; std::for_each (functors.begin(), functor.end(), _1);
The above compiles, but...does nothing. How can I enforce calling of operator () ?
You're just taking the expression (of function type) each time and doing nothing with it. You need to make the call. The following does NOT seem to work, and I'm not sure why: for_each (functors.begin(), functors.end(), _1()); But the following does work: void call(function<void ()> f) { f(); } ... for_each (functors.begin(), functors.end(), call); There may be a better way, but this might do until you find it. -- Michiel Helvensteijn

You need to make the call. The following does NOT seem to work, and I'm not sure why:
for_each (functors.begin(), functors.end(), _1());
Well, that was the experssion I started with. But since it doesn't compile, I thought probably _1 evaluates to (*functor)()...
But the following does work:
void call(function<void ()> f) { f(); } ... for_each (functors.begin(), functors.end(), call);
Yes, sure, but I'd like to create & call in-place lambda functor - with no complicated bindings etc. - just a trivial one. And I still don't belive it's impossible :-)

Igor R <boost.lists <at> gmail.com> writes:
Hi,
std::vector<boost::function<void(void)> > functors; using namespace boost::lambda; std::for_each (functors.begin(), functor.end(), _1);
The above compiles, but...does nothing. How can I enforce calling of operator () ?
typedef boost::function<void(void)> functor; std::vector<functor> functors; ... using namespace boost::lambda; std::for_each( functors.begin(), functors.end(), bind(&functor::operator(),_1)); bind here is boost::lambda::bind, in #include <boost/lambda/bind.hpp>, not to be confused with boost::bind. On the other hand, you can rewrite the stuff using Boost.Bind instead of Boost.Lambda: std::for_each( functors.begin(), functors.end(), boost::bind(&functor::operator(),::_1)); We are using here a different "bind" and a different "_1". This name clash between both Boost libraries is a constant source of grief. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

typedef boost::function<void(void)> functor; std::vector<functor> functors; ... using namespace boost::lambda; std::for_each( functors.begin(), functors.end(), bind(&functor::operator(),_1));
Oh, I see... So the explicit bind is unavoidable :(. Is there any reason for this? After all, lambda allows compact expressions like _1 = 1 , so why wouldn't it allow _1() ?

Igor R [boost.lists@gmail.com], le 17 juillet 2008 10:09:
typedef boost::function<void(void)> functor; std::vector<functor> functors; ... using namespace boost::lambda; std::for_each( functors.begin(), functors.end(), bind(&functor::operator(),_1));
Oh, I see... So the explicit bind is unavoidable :(.
As shown here: http://www.boost.org/doc/libs/1_35_0/doc/html/lambda/le_in_details.html#lamb..., the bind() is unavoidable, but it does not have to be that explicit. This should work: std::for_each(functors.begin(), functors.end(), bind(_1)); Note that Lambda may be unable to deduce the return type for some functors. See http://www.boost.org/doc/libs/1_35_0/doc/html/lambda/le_in_details.html#lamb... for more information. Éric Malenfant --------------------------------------------- Sometimes I think the surest sign that intelligent life exists elsewhere in the universe is that none of it has tried to contact us. - Calvin

Eric MALENFANT escribió:
Igor R [boost.lists@gmail.com], le 17 juillet 2008 10:09:
typedef boost::function<void(void)> functor; std::vector<functor> functors; ... using namespace boost::lambda; std::for_each( functors.begin(), functors.end(), bind(&functor::operator(),_1));
Oh, I see... So the explicit bind is unavoidable :(.
As shown here: http://www.boost.org/doc/libs/1_35_0/doc/html/lambda/le_in_details.html#lamb..., the bind() is unavoidable, but it does not have to be that explicit. This should work:
std::for_each(functors.begin(), functors.end(), bind(_1));
Cute! Hadn't realized the first argument of bind can also be filled by a placeholder. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

joaquin@tid.es escribió:
Eric MALENFANT escribió:
As shown here: http://www.boost.org/doc/libs/1_35_0/doc/html/lambda/le_in_details.html#lamb..., the bind() is unavoidable, but it does not have to be that explicit. This should work: std::for_each(functors.begin(), functors.end(), bind(_1));
Cute! Hadn't realized the first argument of bind can also be filled by a placeholder.
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
With Boost.Bind, however, the same trick does not work: std::for_each( functors.begin(), functors.end(), boost::bind(::_1)); This does not invoke operator() on the functor objects. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Great, thanks a lot to both of you!
As shown here: http://www.boost.org/doc/libs/1_35_0/doc/html/lambda/le_in_details.html#lamb..., the bind() is unavoidable, but it does not have to be that explicit. This should work: std::for_each(functors.begin(), functors.end(), bind(_1));
Cute! Hadn't realized the first argument of bind can also be filled by a placeholder.
Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
With Boost.Bind, however, the same trick does not work:
std::for_each( functors.begin(), functors.end(), boost::bind(::_1));
This does not invoke operator() on the functor objects.

<joaquin <at> tid.es> writes:
With Boost.Bind, however, the same trick does not work:
std::for_each( functors.begin(), functors.end(), boost::bind(::_1));
This does not invoke operator() on the functor objects.
For Boost.Bind there is boost::apply. #include "boost/bind/apply.hpp" for_each(f.begin(), f.end(), bind(apply<void>(), _1)); Roman Perepelitsa.
participants (6)
-
Eric MALENFANT
-
Igor R
-
Joaquin M Lopez Munoz
-
joaquin@tid.es
-
Michiel Helvensteijn
-
Roman Perepelitsa