Reputation: 4114
Assumed I would like to add two vectors a
and b
into a vector c
std::vector<double> a, b, c;
//Fill/Initialize vectors
I can either use std::transform()
or a simple for
-loop:
//std::transform
std::transform(a.begin(),
a.end(),
b.begin(),
c.begin(),
[](const auto &a_val, const auto &b_val){
return a_val + b_val;
});
//Loop
for(size_t i = 0; i < a.size(); ++i){
c[i] = a[i] + b[i];
}
Usually, using std::transform()
is recommended compaired to a for
-loop. Unfortunately, as far as I know, I can not do a similar approach using std::transform()
for the case of adding up more vectors than two, i.e. if I would like to add up the vectors a
, b
and c
into d. Then I'm back to the for-loop, or I have to use two rounds of std::transform()
. Or is there a way of using a single std::transform()
-operation (or something similar) for operating on more than two input vectors at the same time?
Upvotes: 6
Views: 1960
Reputation: 122468
If you are fine with creating another vector you can do this:
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
int main() {
std::vector<int> a{1,2,3,4};
std::vector<int> b{1,2,3,4};
std::vector<int> c(a.size());
std::vector<int> v(a.size());
std::iota(v.begin(), v.end(),0);
std::transform(v.begin(),
v.end(),
c.begin(),
[&](const auto &i){
return a[i] + b[i];
});
for (const auto& e : c) std::cout << e << ' ';
return 0;
}
You could turn the lambda into something more generic, eg a functor that works on variadic number of vectors and adds their elements.
However, I would prefer the loop. Main advantage of algorithms is clarity, but if you need to resort to a workaround that clarity is lost. Maybe someone can proove me wrong and find an algorithm that can do what you want out of the box ;).
PS: on a second thought the above is really silly and a misuse of the algorithm. With the help of std::iota
any loop can trivially be transformed to using an algorithm, but the true meaning of std::transform
"transform one range to another" is completely lost which defeats the purpose of using an algorithm in the first place.
Upvotes: 1
Reputation: 10315
It's true, in standard library this is impossible to std::transform
more than 2 vectors. But using range-v3
you can do it with arbitrary number of vectors using zip
.
#include <include/range/v3/view/zip.hpp>
int main()
{
std::vector<int> a{1,2,3};
std::vector<int> b{2,3,4};
std::vector<int> c{2,3,4};
std::vector<int> d{2,3,4};
std::vector<int> res;
auto r = ranges::views::zip(a, b, c, d);
std::transform(
r.begin(),
r.end(),
std::back_inserter(res),
[](const auto& tup) { return std::get<0>(tup); }
);
}
Upvotes: 6