Search code examples
c++boost-bind

How to reimplement this with std algorithms?


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?


Solution

  • 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!