Подтвердить что ты не робот

Std:: transform с использованием выражения С++ 0x lambda

Как это делается в С++ 0x?

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

Оригинальный вопрос и решение здесь.

4b9b3361

Ответ 1

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

Ответ 2

Просто, как говорит Дарио:

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

for_each разрешено изменять элементы, говоря, что это не может быть мифом.

Ответ 3

Основная оригинальная мотивация использования этого функционального стиля для этих случаев в С++ была "aaagh! iterator loops!", а С++ 0x удаляет эту мотивацию с помощью оператора range. Я знаю, что часть вопроса заключалась в том, чтобы выяснить синтаксис лямбда, но я думаю, что ответ на вопрос "Как это делается в С++ 0x?"? является:

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

Там нет реального объекта функции, но если это поможет вам сделать вид, что { a *= 3; } - это очень сокращенная лямбда. Для удобства использования он имеет одно и то же значение, хотя в проекте стандарта определяется диапазон, основанный на эквивалентном цикле for.

Ответ 4

Используя изменяемый подход, мы можем использовать for_each для непосредственного обновления элементов последовательности через ссылки.

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


Происходили некоторые дебаты, если for_each действительно разрешено изменять элементы, так как он называется "не мутирующим" алгоритмом.

То, что означает for_each, не позволяет изменять последовательность, в которой он работает (что относится к изменениям последовательности структуры - то есть к недействительным итераторам). Это не означает, что мы не можем изменять неконстантные элементы вектора, как обычно, - сама структура остается нетронутой этими операциями.

Ответ 5

Вот так:

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

Ответ 6

Я использую VS2012, который поддерживает адаптер связывания С++ 11. Чтобы связать первый элемент двоичной функции (как использовать bind1st), вам нужно добавить _1 (аргумент заполнителя). Необходимо включить функционал для привязки.

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