Steve Townsend
Steve Townsend

Reputation: 54178

std::transform using C++0x lambda expression

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.

Upvotes: 35

Views: 38388

Answers (6)

Elligno
Elligno

Reputation: 79

I'm using VS2012 which support the C++11 bind adaptor. To bind the first element of the binary function (as bind1st use to do) you need to add an _1 (placeholder argument). Need to include the functional for bind.

using namespace std::placeholders;
std::transform( myv1.begin(), myv1.end(), myv1.begin(),
                 std::bind( std::multiplies<double>(),3,_1));

Upvotes: 1

Edward Strange
Edward Strange

Reputation: 40895

std::transform(myv1.begin(), myv1.end(), myv1.begin(), 
   [](double d) -> double { return d * 3; });

Upvotes: 42

John Dibling
John Dibling

Reputation: 101506

Like this:

vector<double> myv1;
transform(myv1.begin(), myv1.end(), myv1.begin(), [](double v)
{
    return v*3.0;
});

Upvotes: 6

Steve Jessop
Steve Jessop

Reputation: 279455

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.

Upvotes: 32

Dario
Dario

Reputation: 49238

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.

Upvotes: 8

GManNickG
GManNickG

Reputation: 504333

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.

Upvotes: 28

Related Questions