Re: [Boost-users] A question about boost::lambda::if_ behavior
Hello Bjorn, Thanks for such a quick help. I works now. Can you please further explain the usage of var and constant . in the expression if_(_1 < 24.000001 && _1 > 23.999999)[ cout <<"Bingo:<"<<_1<<">"]) I understand "Bingo:<" is evaluated immediately, why not ">", which is not a lambda expression either, is not evaluated along. Forgive me if this question seems stupid, but I am new to Lambda, fascinated by its power, but convoluted by its mechanism yet. Thanks. -----Original Message----- From: tom gee [mailto:rockonedge@gmail.com] Subject: [Boost-users] A question about boost::lambda::if_ behavior
Can anyone please explain this code: [snip]
The problem is that the expression std::cout << constant("Bingo:<") is evaluated immediately. Why? Because it's not a lambda expression. You have two options that will help you turn your if-branch into a lambda expression; either use boost::lambda::var or boost::lambda::constant. Using boost::lambda::var: std::for_each(setFinalVal.begin(),setFinalVal.end(), (std::cout << _1 << " ", if_(_1 < 24.000001 && _1 > 23.999999) [var(std::cout) << "Bingo:<" << _1 << ">"])); Using boost::lambda::constant: std::for_each(setFinalVal.begin(),setFinalVal.end(), (std::cout << _1 << " ", if_(_1 < 24.000001 && _1 > 23.999999) [std::cout << constant("Bingo:<") << _1 << ">"])); Cheers, Bjorn Karlsson
tom gee wrote:
Hello Bjorn,
Thanks for such a quick help. I works now.
Can you please further explain the usage of var and constant . in the expression if_(_1 < 24.000001 && _1 > 23.999999)[ cout <<"Bingo:<"<<_1<<">"]) I understand "Bingo:<" is evaluated immediately, why not ">", which is not a lambda expression either, is not evaluated along.
Refresher course: an expression like: cout << foo << bar << endl; is read (aka parsed) by the compiler to be shorthand for the following: (((cout << foo) << bar) << endl); which, incidently is just shorthand for: operator<<(operator<<(operator<<(cout, foo), bar), endl); Thus, '<<' is known as a 'left assosiative' (I think :D) operator. Refresher over. Basicly, the 'cout << "Bingo:<"' sub-expression has no 'lambda stuff' in it, and therefore calls the _normal_ operator<<, which immediately prints "Bingo:<". This operator<< returns a reference to cout, so the next '<<' sees: cout << _1 Which (obviously) is an expression containing a lambda (sub-)expression. The guys who made this library were nice enough to provide overloads of '<<' (along with every other possible operator) that return a 'lambda function object', you just have to know that it is a valid lambda expression that _will_ evalute as "cout << _the_first_argument_" when called. The same happens with the next <<, it sees: _lambda_operator_left_shift_ << ">" , where the left argument is the previous lambda function object made from the "cout << _1" sub-expression. Now there is _another_ overload of << that creates _another_ lambda function object, that _will_ evalute as if it was: cout << _the_first_argument_ << ">" So, basicly, anytime there is a sub-expression that doesn't have a lambda object in it, it is treated as a normal expression, but if it does, it creates a function object that will do what it looks like it would do. What 'constant' and 'var' do is make a (lambda?) function object that just returns it's argument, as, respectively, a constant copy, or a reference to the original (I think, again, use boost::ref to be sure)
Forgive me if this question seems stupid, but I am new to Lambda, fascinated by its power, but convoluted by its mechanism yet.
Thanks.
[snip]
Don't worry about it, but don't forget to read the documentation!
One more thing to keep in mind, the overload for '()', the call
operator, for a lambda function object immeadiatly evaluates it's
contained expression, ie:
(_1 + 3)(4) == (4 + 3);
to get around this if you want to delay a call to that object, use:
boost::lambda::bind(_1 + 3, 4);
which returns a lambda function object that when called, calls the first
argument with the rest of bind's arguments as it's arguments, so:
bind(_1 + 3, 4)() == (_1 + 3)(4) == (4 + 3)
Which is VERY usefull if you want to, say call functions in a STL container:
int i, j;
std::vector
participants (2)
-
Simon Buchan
-
tom gee