tags:

views:

144

answers:

2

I'm trying to change the integer values in a vector using transform and an if_then_else control structure from Boost Lambda. However my compiler is not appreciating my efforts. The code I am attempting is:

transform(theVec.begin(), theVec.end(), theVec.begin(), 
          if_then_else(bind(rand) % ratio == 0, _1 = bind(rand) % maxSize, _1));

I tried simplifying it to the following:

transform(theVec.begin(), theVec.end(), theVec.begin(),
          if_then_else(0 == 0, _1 = MaxIntSizeCFG, _1));

but the compiler tells me: no matching function for call to 'if_then_else(..........' I read that the return values from control structures is void, so is my attempted usage in this case entirely wrong?

Thanks in advance for your time!

+1  A: 

if_then_else in your usage is incorrect, in the same way this is:

int i = if (some_condition){ 0; } else { 1; };

What you want is merely the ternary operator; however, this won't work in a lambda. You can simulate this with the the if_then_else_return structure instead. (i.e., you were close!)

The if_then_else is for something like a for_each loop, where you'd take one action or the other depending on a condition. The if_then_else_return is for a ternary conditional.

GMan
Ah yes of course nothing is being passed back with the if_the_else structure. I tried:transform(theVec.begin(), theVec.end(), theVec.begin(), if_then_else_return(bind(rand) % ratio == 0, _1 = bind(rand) % maxSize, _1));and this worked fine. Thanks!
Demps
No problems, I'll be waiting for your next lambda question. :P
GMan
Haha, its queuing up! Actually can you recommend a good resource for lambada expression? I've only just started using them (as you can tell) and I'm well impressed by what can be done.
Demps
@Demps: I can't recommend more than the Boost lambda reference, unfortunately. In honestly, be careful. Lambda's are cool and easy to over-use. If you're using Boost, I recommend for-each most of the time. Lambda's are good when you really need a functor, foreach is good when you really want to loop over some elements.
GMan
+1  A: 

Since you already use Boost I recommend BOOST_FOREACH instead of such a complex lambda expression:

BOOST_FOREACH(int & i, v)
    i = rand() % ratio ? i : rand();

This will be very easy to adapt once the new range-based for loop becomes available:

for(int & i : v)
    i = rand() % ratio ? i : rand();
Manuel
are there already compilers which allow the second syntax for experimental usage?
Rupert Jones
@rjones - Concept GCC supports it since 2007 (!) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2196.html. Major compilers are are taking longer because of the removal of concepts from the upcoming standard
Manuel