G-71
G-71

Reputation: 3682

Changing all elements in vector(list, deque...) using C++11 Lambda functions

I have the following code:

#include <iostream>
#include <vector>
#include <algorithm>

int main( int argc, char* argv[] )
{
    std::vector< int > obj;
    obj.push_back( 10 );
    obj.push_back( 20 );
    obj.push_back( 30 );
    std::for_each( obj.begin(), obj.end(), []( int x )
    { 
        return x + 2; 
    } );
    for( int &v : obj )
        std::cout << v << " ";
    std::cout << std::endl;
    return 0;
}

The result is : 10, 20, 30

i want to change all elements in vector (obj), using Lambda functions of new C++11 standard.

This is the code of implementation for_each function:

template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
    for ( ; first!=last; ++first )
        f(*first);
    return f;
}

*first passed by value and cope of element is changed, what is the alternative of for_each i must use that i have a result: 12, 22, 32 ?

Upvotes: 6

Views: 7990

Answers (5)

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361442

i want to change all elements in vector (obj), using Lambda functions of new C++11 standard.

You've to do this :

std::for_each( obj.begin(), obj.end(), [](int & x)
{                                          //^^^ take argument by reference
   x += 2; 
});

In your (not my) code, the return type of the lambda is deduced as int, but the return value is ignored as nobody uses it. That is why there is no return statement in my code, and the return type is deduced as void for this code.

By the way, I find the range-based for loop less verbose than std::for_each for this purpose:

for( int &v : obj )  v += 2;

Upvotes: 17

Christian Rau
Christian Rau

Reputation: 45948

In addition to the already existing (and perfectly correct) answers, you can also use your existing lambda function, that returns the result instead of modifying the argument, and just use std::transform instead of std::for_each:

std::transform(obj.begin(), obj.end(), obj.begin(), []( int x )
{
    return x + 2;
} ); 

Upvotes: 3

reima
reima

Reputation: 2126

You should use transform:

std::transform( obj.begin(), obj.end(), obj.begin(), []( int x )
{ 
    return x + 2; 
} );

Upvotes: 8

joy
joy

Reputation: 1569

std::for_each( obj.begin(), obj.end(), []( int& x )
{ 
     x += 2; 
} );

Upvotes: 3

Kerrek SB
Kerrek SB

Reputation: 477040

Pass the argument by reference and modify the reference:

std::for_each( obj.begin(), obj.end(), [](int & x){ x += 2; } );
//                                        ^^^^^

Upvotes: 7

Related Questions