views:

152

answers:

5

How is this done in C++0x?

std::vector<double> myv1;
std::transform(myv1.begin(), myv1.end(), myv1.begin(),
               std::bind1st(std::multiplies<double>(),3));

Original question and solution is here.

+4  A: 
std::transform(myv1.begin(), myv1.end(), myv1.begin(), [](double d) -> double { return d * 3; });
Noah Roberts
`-> double` is unnecessary; it gets automatically deduced.
Potatoswatter
@Noah - thanks v much
Steve Townsend
@potato - it's supposed to, but current compilers sometimes ignore this fact. Better to just put it in all the time.
Noah Roberts
+2  A: 

Like this:

vector<double> myv1;
transform(myv1.begin(), myv1.end(), myv1.begin(), [](double v)
{
    return v*3.0;
}
);
John Dibling
I find that formatting pretty confusing.
Potatoswatter
To each his own, I suppose. Tho I hasten to point out that mine *is* the correct formatting. :)
John Dibling
+1 for actually using a literal double for the constant. ;-)
Adrian McCarthy
+10  A: 

Just do as Dario says:

for_each(begin(myv1), end(myv1), [](double& a) { a *= 3; });

for_each is allowed to modify elements, saying it cannot is a myth.

GMan
+1 because this seems a more natural fit to me in the original question
Steve Townsend
+1 for "for_each is allowed to modify elements." I participated in a very heated debate about this years ago.
John Dibling
+3  A: 

Using a mutable approach, we can use for_each to directly update the sequence elements through references.

for_each(begin(myv1), end(myv1), [](double& a) { a *= 3; });


There has been some debate going on if for_each is actually allowed to modify elements as it's called a "non-mutating" algorithm.

What that means is for_each isn't allowed to alter the sequence it operates on (which refers to changes of the sequence structure - i.e. invalidating iterators). This doesn't mean we cannot modify the non-const elements of the vector as usual - the structure itself is left untouched by these operations.

Dario
+7  A: 

The main original motivation for using that functional style for these cases in C++ was, "aaagh! iterator loops!", and C++0x removes that motivation with the range-based for statement. I know that part of the point of the question was to find out the lambda syntax, but I think the answer to the question "How is this done in C++0x?" is:

for(double &a : myv1) { a *= 3; }

There's no actual function object there, but if it helps you could pretend that { a *= 3; } is a highly abbreviated lambda. For usability it amounts to the same thing either way, although the draft standard defines range-based for in terms of an equivalent for loop.

Steve Jessop
@Steve: Ah yah. I typically forget about that since I don't use a compiler that supports it. :( Definitely the best solution.
GMan
@Steve - what's the name for this construct? I am still not familiar with what's in C++0x.
Steve Townsend
@Steve: "range-based for statement", 6.5.4 in n3090. Added to the answer.
Steve Jessop
@Steve Townsend. I think it's called 'ranged-based for-loop'. In Java this same construct is called foreach =/
KitsuneYMG