[lambda] How to write a lambda functor that returns a new functor

Hi,
How can I write a lambda expression with two placeholders, one for the
callable object, and one for the function argument, such that supplying
the callable object first returns a unary function?
In the example below, generate should be a lambda expression with the
first placeholder for the callable object itself, and the second
placeholder for the argument. Calling generate(c) should return a unary
function that is only missing the function call argument. In fact, it
somehow returns type bool already, as proved by the static assert.
#include

AMDG On 03/09/2011 06:11 AM, Sebastian Theophil wrote:
How can I write a lambda expression with two placeholders, one for the callable object, and one for the function argument, such that supplying the callable object first returns a unary function?
In this case, boost::lambda::_1 by itself does what you want, because the callable object itself is a unary function.
In the example below, generate should be a lambda expression with the first placeholder for the callable object itself, and the second placeholder for the argument. Calling generate(c) should return a unary function that is only missing the function call argument. In fact, it somehow returns type bool already, as proved by the static assert.
#include
struct Arg { };
struct Callable : std::unary_function
{ bool operator()( Arg const& a ) const { return true; } }; int main( int argc, const char* argv[] ) { BOOST_AUTO(generate, boost::lambda::bind(boost::lambda::_1, boost::lambda::protect(boost::lambda::_1)));
generate(c) will end up calling c(boost::lambda::_1).
Callable c; BOOST_AUTO(fn, generate(c));
BOOST_STATIC_ASSERT((boost::is_same
::value)); Arg a; bool b = fn(a); _ASSERT(b==true); }
In Christ, Steven Watanabe

Steven,
On 03/09/2011 06:11 AM, Sebastian Theophil wrote:
How can I write a lambda expression with two placeholders, one for
callable object, and one for the function argument, such that supplying the callable object first returns a unary function?
In this case, boost::lambda::_1 by itself does what you want, because
the the
callable object itself is a unary function.
That is true of course, I was trying to solve a slightly more
complicated problem though. I have solved the problem finally, although
I hoped there was a more elegant solution:
struct FCreateBind {
typedef boost::_bi::bind_t

On Thu, Mar 10, 2011 at 11:12 AM, Sebastian Theophil
Steven,
On 03/09/2011 06:11 AM, Sebastian Theophil wrote:
How can I write a lambda expression with two placeholders, one for
callable object, and one for the function argument, such that supplying the callable object first returns a unary function?
In this case, boost::lambda::_1 by itself does what you want, because
the the
callable object itself is a unary function.
That is true of course, I was trying to solve a slightly more complicated problem though. I have solved the problem finally, although I hoped there was a more elegant solution:
struct FCreateBind { typedef boost::_bi::bind_t
, boost::arg<2> > > result_type; result_type operator()( Callable const& c ) const { return boost::bind<bool>(c, _1); } }; BOOST_AUTO(generate, boost::bind(FCreateBind(), _1)); BOOST_AUTO(fn, generate(Callable()); bool b = fn(Arg());
Of course, in this simple example I could just write BOOST_AUTO(generate, boost::lambda::_1) since Callable itself is the callable object. But I was looking for a way to set the arguments of Callable beforehand so the generated function fn is a nullary function. This solution would let me do this inside FCreateBind.
FCreateBind can probably be eliminated as well, but I have not yet figured out how to define the pointer to the overloaded global function boost::bind.
Regards Sebastian
Hi, Sorry for the late reply, what you were trying to achieve is possible with phoenix V3 (doesn't seem to work with V2). Here is the code: using boost::phoenix::lambda; using boost::phoenix::bind; using boost::phoenix::placeholders::_1; using boost::phoenix::local_names::_a; auto const generate = lambda(_a = _1)[bind(_a, _1)]; auto const fn = generate(Callable()); Here is how it works: generate is a lambda that binds its first argument (this is done by capturing the actual argument to a local). By calling generate with an appropriate callable the returned function can be called again which effectively leads to the execution of the bind call. You currently need to define the functions as "auto const" cause there is a bug in the result type deduction (will be fixed soon). HTH, Thomas

On Thu, Mar 10, 2011 at 12:50 PM, Thomas Heller
On Thu, Mar 10, 2011 at 11:12 AM, Sebastian Theophil
wrote: Steven,
On 03/09/2011 06:11 AM, Sebastian Theophil wrote:
How can I write a lambda expression with two placeholders, one for
callable object, and one for the function argument, such that supplying the callable object first returns a unary function?
In this case, boost::lambda::_1 by itself does what you want, because
the the
callable object itself is a unary function.
That is true of course, I was trying to solve a slightly more complicated problem though. I have solved the problem finally, although I hoped there was a more elegant solution:
struct FCreateBind { typedef boost::_bi::bind_t
, boost::arg<2> > > result_type; result_type operator()( Callable const& c ) const { return boost::bind<bool>(c, _1); } }; BOOST_AUTO(generate, boost::bind(FCreateBind(), _1)); BOOST_AUTO(fn, generate(Callable()); bool b = fn(Arg());
Of course, in this simple example I could just write BOOST_AUTO(generate, boost::lambda::_1) since Callable itself is the callable object. But I was looking for a way to set the arguments of Callable beforehand so the generated function fn is a nullary function. This solution would let me do this inside FCreateBind.
FCreateBind can probably be eliminated as well, but I have not yet figured out how to define the pointer to the overloaded global function boost::bind.
Regards Sebastian
Hi,
Sorry for the late reply, what you were trying to achieve is possible with phoenix V3 (doesn't seem to work with V2). Here is the code:
It turns out it does work with V2 ... the trick is to not use temporaries with phoenix V2 ... and callable has to be adapted to conform to the phoenix result type deduction protocol
using boost::phoenix::lambda; using boost::phoenix::bind; using boost::phoenix::placeholders::_1; using boost::phoenix::local_names::_a;
auto const generate = lambda(_a = _1)[bind(_a, _1)]; auto const fn = generate(Callable());
Here is how it works: generate is a lambda that binds its first argument (this is done by capturing the actual argument to a local). By calling generate with an appropriate callable the returned function can be called again which effectively leads to the execution of the bind call. You currently need to define the functions as "auto const" cause there is a bug in the result type deduction (will be fixed soon).
HTH, Thomas
participants (3)
-
Sebastian Theophil
-
Steven Watanabe
-
Thomas Heller