If I like to accumulate the absolute values of a std::vector
, I can use a lambda to calculate the absolute value and add it to the sum of std::accumulate
(live demo).
#include <numeric>
#include <vector>
int main (){
std::vector<int> vec {1,2,3,-4};
auto abs_val =[](auto val, auto sum){return sum + std::fabs(val);};
return std::accumulate(vec.begin(), vec.end(), 0, abs_val);
}
I would like to write
return std::accumulate(vec.begin(), vec.end(), 0, std::fabs());
but this does not compile, since a function with the two arguments sum
and value
is expected.
Is there a more elegant way to write this? Do I need the lambda? Can I get rid of it?
Before C++17
You basically want to do two things: Transform the elements and then sum them. For std::accumulate
you have to tell the algorithm how you want to sum the elements up, but if you want to transform the elements, you need to do something extra.
The line you want to write only tells how to transform the elements (and it doesnt compile, because accumulate
expects a functor that adds elements not one that transforms them).
TL;DR: No. If you want to transform and add elements, you have to do both. There is no algorithm called transform_and_accumulate
, so you have to combine something yourself.
C++17
The above is true only till C++17, which has transform_reduce
and that basically does what you are looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With