Как это делается в С++ 0x?
std::vector<double> myv1;
std::transform(myv1.begin(), myv1.end(), myv1.begin(),
std::bind1st(std::multiplies<double>(),3));
Оригинальный вопрос и решение здесь.
Как это делается в С++ 0x?
std::vector<double> myv1;
std::transform(myv1.begin(), myv1.end(), myv1.begin(),
std::bind1st(std::multiplies<double>(),3));
Оригинальный вопрос и решение здесь.
std::transform(myv1.begin(), myv1.end(), myv1.begin(),
[](double d) -> double { return d * 3; });
Просто, как говорит Дарио:
for_each(begin(myv1), end(myv1), [](double& a) { a *= 3; });
for_each
разрешено изменять элементы, говоря, что это не может быть мифом.
Основная оригинальная мотивация использования этого функционального стиля для этих случаев в С++ была "aaagh! iterator loops!", а С++ 0x удаляет эту мотивацию с помощью оператора range. Я знаю, что часть вопроса заключалась в том, чтобы выяснить синтаксис лямбда, но я думаю, что ответ на вопрос "Как это делается в С++ 0x?"? является:
for(double &a : myv1) { a *= 3; }
Там нет реального объекта функции, но если это поможет вам сделать вид, что { a *= 3; }
- это очень сокращенная лямбда. Для удобства использования он имеет одно и то же значение, хотя в проекте стандарта определяется диапазон, основанный на эквивалентном цикле for
.
Используя изменяемый подход, мы можем использовать for_each
для непосредственного обновления элементов последовательности через ссылки.
for_each(begin(myv1), end(myv1), [](double& a) { a *= 3; });
for_each
действительно разрешено изменять элементы, так как он называется "не мутирующим" алгоритмом.
То, что означает for_each
, не позволяет изменять последовательность, в которой он работает (что относится к изменениям последовательности структуры - то есть к недействительным итераторам). Это не означает, что мы не можем изменять неконстантные элементы вектора, как обычно, - сама структура остается нетронутой этими операциями.
Вот так:
vector<double> myv1;
transform(myv1.begin(), myv1.end(), myv1.begin(), [](double v)
{
return v*3.0;
});
Я использую VS2012, который поддерживает адаптер связывания С++ 11. Чтобы связать первый элемент двоичной функции (как использовать bind1st), вам нужно добавить _1 (аргумент заполнителя). Необходимо включить функционал для привязки.
using namespace std::placeholders;
std::transform( myv1.begin(), myv1.end(), myv1.begin(),
std::bind( std::multiplies<double>(),3,_1));