Boost logo

Boost Users :

From: Martin Young (martin_at_[hidden])
Date: 2006-11-09 06:51:05


Hi,

I've just started trying to use the Boost lambda library and I'm finding
that I can't get anything much to work how I'd expect. I've read the docs
and I'm none the wiser. I'm running on Cygwin using GCC 3.4.4 if that makes
any difference. My problem is pretty nebulous - I can't get the
non-workingness nailed down a specific issue - whenever I try something
different I get several screenfulls of different error messages.

So, previously I had a alot of code in the form below which performs linear
searches of a vector. Clearly this is not the Right Thing, especially as I
will want to change the vectors to different containers at a later point.

typedef struct
{
   int a;
   void* b;
} foo;
vector<foo*>* v = buildAndPopulateVector();
for( int i=0, iL=v->size(); i<iL; i++ )
{
   foo* thisFoo = (*v)[i];
   if( thisFoo->a == 0 )
   {
       thisFoo->a = 1;
       *(int*)(thisFoo->b) = 42;
   }
}

Instead, I'd like to use the for_each algorithm to iterate over the contents
of the vector like this:

foreach( v->begin(), b->end(), ### )

Where the ### would normally be a function pointer (or relative thereof).
I'd like to use lambda so I can put my code inline. At first I thought I
could do something like:

foreach( v->being(), b->end(),
   if_then( _1->a == 0,
   (
       _1->a = 1,
       *(int*)(_1->b) = 42
   )
)

I quickly discovered that the placeholders don't work like that and a pile
of bind and/or ->* operators are required to extract any interesting
information. I think I've got this bit sorted now though.

What I'm getting stuck on now is constructing a working version of the
if/then construct. The condition expression seems okay...

if_then( bind(&foo::a,_1)==0,

but I just can't get the "body" part to compile. I have to enclose it in
round brackets so it appears as one expression to the compiler, but then
it's not a lambda expression so I need to wrap it in something to make it a
lambda. I should then pass _1 in as the single parameter of my new nested
lambda because the previous _1 won't be in scope anymore - is this right?

Is there another (better) way to include multiple expressions in an if_then
construct without making a nested lambda and thus losing the bindings from
the original lambda?

What should I wrap my expression in to make it a unary lambda into which I
can pass _1 from the main lambda? It's not getting automatically picked up
as a lambda expression because the use of _1 is in the middle of one of the
comma separated sub exprssions. Can I even pass _1 into a nested lambda like
that or does it need massaging first? I've found dealing with the
placeholders to be very painful so far...

Are there any examples of this kind of thing anywhere? All the examples I've
found are incomplete or for very trivial cases, or have not been answered.
Even the "Beyond the std lib/boost" book has only very simple examples and
esoteric gotchas. It seems to me this ought to be a very simple thing - am I
going about it in the wrong way?

I've had a good Google and a read through this list's archives and there
seems to be very little discussion about the lambda library. Is it moribund
or am I the only person who can't make it work?

Sorry for all the rather vague questions and thanks for any pointers.

 -Martin.


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