I have a container of pointers to objects. The pointers are a base class, and the hierarchy implements a virtual function count()
. I want to calculate a sum of count()
in the container.
I currently do this with for_each
and a lambda function:
size_t sum = 0;
std::for_each(ptrs_.begin(), ptrs_.end(), [&sum](ptr const *p) {
expr += p->count();
});
return sum;
Can anyone help me reimplement this with boost::bind
and std::accumulate
or other std algorithms?
auto getcount = std::mem_fun(&Base::count); // nothing to bind, we just need a functor
size_t sum = std::accumulate(
boost::make_transform_iterator(ptrs_.begin(), getcount),
boost::make_transform_iterator(ptrs_.end(), getcount),
(size_t)0
);
If you don't like auto
, or more likely if your compiler doesn't, then of course you can paste the thing twice, or go looking for the return type of mem_fun
, or capture it using a function template:
template <typename IT, typename FUNC, typename T>
T transform_accumulate(IT first, IT last, T init, FUNC func) {
return std::accumulate(
boost::make_transform_iterator(first, func),
boost::make_transform_iterator(last, func),
init
);
}
Then call it as:
transform_accumulate(ptrs_.begin(), ptrs_.end(), size_t(), std::mem_fun(&Base::count));
Alternately, use the form of std::accumulate
that takes a binary functor:
struct AddCount {
size_t operator()(size_t result, Base *p) const {
return result + p->count();
}
};
size_t sum = std::accumulate(ptrs_.begin(), ptrs_.end(), size_t(), AddCount());
Instead of writing AddCount
, you could of course use a lambda expression. I expect you can construct it using the stuff in <functional>
too, but I'm not going to.
I haven't tested any of this code, so let the error-spotting begin!