$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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.