If I want to calculate the sum of a bunch of numbers retrieved from an std::istream
, I can do the following:
// std::istream & is = ...
int total = std::accumulate(std::istream_iterator<int>(is),
std::istream_iterator<int>(),
0);
However, if I want to calculate their average, I need to accumulate two different results:
std::accumulate
)std::distance
)Is there any way to "merge" these two algorithms and run them "side by side" in a single pass of an iterator range? I would like to do something like:
using std::placeholders;
int total, count;
std::tie(total, count) = merge_somehow(std::istream_iterator<int>(is),
std::istream_iterator<int>(),
std::bind(std::accumulate, _1, _2, 0),
std::distance);
double average = (double)total / count;
Is this possible?
A ready-made solution for this sort of single-pass accumulation is implemented by Boost.Accumulators. You make a single accumulator, say for sum, count and average, populate it, and then extract all three results at the end.
You cannot merge two different algorithms to be interleaved. The algorithms control the flow, and you can only have one flow. Now, in your particular case you can simulate it:
int count = 0;
int total = std::accumulate(std::istream_iterator<int>(is),
std::istream_iterator<int>(),
0,
[&](int x, int y) { ++count; return x+y; });
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