STL способ добавить постоянное значение к std::vector
Есть ли в стандартной библиотеке алгоритм, который может добавить значение для каждого элемента std::vector?
Что-то вроде
std::vector<double> myvec(5,0.);
std::add_constant(myvec.begin(), myvec.end(), 1.);
который добавляет значение 1.0 к каждому элементу?
Если в STL нет хорошего (например, короткого, красивого, легко читаемого) способа, как насчет boost?
Ответы
Ответ 1
Взгляните на std::for_each
и std::transform
. Последний принимает три итератора (начало и конец последовательности и начало выходной последовательности) и объект функции. Есть несколько способов написать это. В одном случае, используя только стандартные элементы, это:
transform(myvec.begin(), myvec.end(), myvec.begin(),
bind2nd(std::plus<double>(), 1.0));
Вы можете сделать это с помощью for_each
, но поведение по умолчанию std::plus
не будет отвечать на исходный вектор. В этом случае вы должны написать свой собственный функтор. Простой пример:
struct AddVal
{
double val;
AddVal(double v) : val(v);
void operator()(double &elem) const
{
elem += v;
}
};
std::for_each(myvec.begin(), myvec.end(), AddVal(1.0));
Ответ 2
Еще короче использование lambda fuctions, если вы используете С++ 0x:
std::for_each(myvec.begin(), myvec.end(), [](double& d) { d+=1.0;});
Ответ 3
Самый короткий путь в простой С++ 0X:
for(double& d : myvec)
d += 1.0;
и с boost:
for_each(myvec, _1 += 1.0); // boost.range + boost.lambda
Ответ 4
std::transform( myvec.begin(), myvec.end(),
myvec.begin(), std::bind2nd( std::plus<double>(), 1.0 ) );
Ответ 5
Если вы заинтересованы в выполнении большого количества математики на векторах, вы можете захотеть заглянуть в часть <valarray>
стандартной библиотеки. Это в основном a std::vector<>
, предназначенное для векторных численных вычислений (срезы, математические функции, точечные операторы и т.д.).
Единственная часть, которая действительно отстойная, состоит в том, что она не имеет простых преобразований и от std::vector<>
.