Boost logo

Boost Users :

From: Jaakko Järvi (jarvi_at_[hidden])
Date: 2006-11-09 23:56:49


Library based lambdas cannot be made perfect, unfortunately.
BLL works in most cases the natural way, and then when it doesn't,
things can be confusing.
One of the biggest issues is that _1.foo() cannot be made to work.

It is hard to give precise advice on your email, but judging from the
discussion on scopes
you may have some confusion on how placeholders work.

A placeholder is "in scope" for the entire lambda expression and will
get the same value everywhere.
That is, all occurrences of _1 are replaced by the same argument (of
type foo* in your example).

Here's a lambda function and a call to it which could be what you are
after (I am not exactly sure what
you wanted to do). As you can see, casts are special too, as they
cannot be overloaded.

Best, Jaakko Järvi

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/casts.hpp>
#include <boost/lambda/if.hpp>
#include <vector>
using namespace boost::lambda;

struct foo
{
    int a;
    void* b;
};

int main () {

   std::vector<foo*> v;
   v.push_back(new foo);

   if_then_else(
                bind(&foo::a, _1) == 0,
                 bind(&foo::a, _1) = 1,
                 (*(ll_reinterpret_cast<int*>(bind(&foo::b, *_1)))) = 42
               )(v[0]);
}

On Nov 9, 2006, at 5:51 AM, Martin Young wrote:

> 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 mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


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