|
Boost Users : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2003-11-21 09:46:55
Allen Bierbaum wrote:
> Hello all.
>
> I am having trouble with the boost lambda library. I am convinced
> that my troubles come from some little thing I am overlooking, but
> for the life of me I can't seem to find the problem. I have been
> looking at it for the entire afternoon with no solution in sight.
>
> I have included some sample code below showing the basic idea of what
> I am trying to accomplish. Can anyone provide me with a working
> solution?
>
> The summary is:
> - I have a vector of shared_ptr's to a class A
> - That class has a method that returns a value I would like to test
> for in a find_if call
[...]
> Can anyone tell me how I can call a method from a lamda method
> iterating over a sequence of shared_ptrs? And then how do I have
> this method also call another method?
The short answer is that you can't, at least with the current
implementation.
There are three possible ways to call a member function with Lambda:
(bl::_1 ->* &Foo::bar )(foo_ptr);
bl::bind(&Foo::bar, *bl::_1)(foo_ptr);
bl::bind(&Foo::bar, bl::_1)(foo_ptr);
The first alternative doesn't work since shared_ptr does not have
operator->*.
The second alternative doesn't work since Lambda doesn't support *_1 for
shared_ptr.
The third alternative doesn't work since it is not supported by Lambda
(probably by design), although it is supported by Bind, and may be supported
by a future version of Lambda.
The Bind equivalent is:
boost::bind(&Foo::bar, _1)(foo_ptr);
and it does work.
Your complete example can be written with Bind as:
std::find_if( foos.begin(), foos.end(),
boost::bind(std::equal_to<int>(),
boost::bind(&A::getInt,
boost::bind(&Foo::bar, _1)
),
find_int
)
);
It is clumsier since the more limited Bind vocabulary forces the use of
std::equal_to instead of simply composing an expression using operator==.
You need to make A::getInt() const, though. Non-const member functions can
be invoked on rvalues, but Bind isn't sophisticated enough to realize that.
I suspect that in your real code getInt is const.
All that said, you might want to rethink whether you want to use Lambda or
Bind in this way here. A helper function would simplify the example
considerably:
bool has_guid(shared_ptr<Foo> const & p, int guid)
{
return p->bar().getInt() == guid;
}
std::find_if( first, last, bind( has_guid, _1, child_guid) );
HTH
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net