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:
- the total sum (
std::accumulate
) - the total count (
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.