Изменение всех элементов вектора (list, deque ...) с помощью лямбда-функций C ++ 11 - PullRequest
3 голосов
/ 10 ноября 2011

У меня есть следующий код:

#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;
}

Результат: 10, 20, 30

Я хочу изменить все элементы в векторе (obj), используя функции Lambda нового стандарта C ++ 11.

Это код реализации for_each функции:

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

* сначала передается по значению и изменяется элемент, что является альтернативой for_each я должен использовать, что у меня есть результат: 12, 22, 32?

Ответы [ 5 ]

13 голосов
/ 10 ноября 2011

Я хочу изменить все элементы в векторе (obj), используя лямбда-функции нового стандарта C ++ 11.

Вы должны сделать это:

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

В вашем (не моем) коде лямбда-тип возвращаемого значения выводится как int, но возвращаемое значение игнорируется, поскольку никто его не использует.Вот почему в моем коде нет оператора return, и для этого кода тип возврата выводится как void.

Кстати, я считаю, что основанный на диапазоне цикл for менее многословен, чем std::for_each для этой цели:

for( int &v : obj )  v += 2;
8 голосов
/ 10 ноября 2011

Вы должны использовать transform:

std::transform( obj.begin(), obj.end(), obj.begin(), []( int x )
{ 
    return x + 2; 
} );
6 голосов
/ 10 ноября 2011

Передайте аргумент по ссылке и измените ссылку:

std::for_each( obj.begin(), obj.end(), [](int & x){ x += 2; } );
//                                        ^^^^^
3 голосов
/ 10 ноября 2011

В дополнение к уже существующим (и совершенно правильным) ответам вы также можете использовать существующую лямбда-функцию, которая возвращает результат вместо изменения аргумента, и просто использовать std::transform вместо std::for_each:

std::transform(obj.begin(), obj.end(), obj.begin(), []( int x )
{
    return x + 2;
} ); 
3 голосов
/ 10 ноября 2011
std::for_each( obj.begin(), obj.end(), []( int& x )
{ 
     x += 2; 
} );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...