Need prettier solution of below example but with std::accumulate.
#include <algorithm>
#include <vector>
#include <iostream>
class Object
{
public:
    Object( double a, double b ):
        a_( a ),
        b_( b )
    {}
    double GetA() const { return a_; }
    double GetB() const { return b_; }
    // other methods
private:
    double a_;
    double b_;
};
class Calculator
{
public:
    Calculator( double& result ):
        result_( result )
    {}
    void operator() ( const Object& object )
    {
        // some formula
        result_ += object.GetA() * object.GetB();
    }
private:
    double& result_;
};
int main()
{
    std::vector< Object > collection;
    collection.push_back( Object( 1, 2 ) );
    collection.push_back( Object( 3, 4 ) );
    double result = 0.0;
    std::for_each( collection.begin(), collection.end(),
                   Calculator( result ) );
    std::cout << "result = " << result << std::endl;
    return 0;
}
                do changes in Calculator and main function.
struct Calculator
{
    double operator() ( double result, const Object& obj )
    {
        return result + ( obj.GetA() * obj.GetB());
    }
};
int main()
{
    std::vector< Object > collection;
    collection.push_back( Object( 1, 2 ) );
    collection.push_back( Object( 3, 4 ) );
    double result = std::accumulate( collection.begin(), collection.end(), 0, Calculator() );
    std::cout << "result = " << result << std::endl;
    return 0;
}
also it could be better:
double sumABProduct( double result, const Object& obj )
{
    return result + ( obj.GetA() * obj.GetB());
}
double result = std::accumulate( collection.begin(), collection.end(), 0, sumABProduct );
                        Update 2: Boost.Lambda makes this a piece of cake:
// headers
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
using namespace boost::lambda;
// ...
cout << accumulate(dv.begin(), dv.end(), 
                   0, 
                   _1 += bind(&strange::value, _2)) //strange defined below
     << endl;
Update: This has been bugging me for a while. I can't just get any of the STL algorithms to work in a decent manner. So, I rolled my own:
// include whatever ...
using namespace std;
// custom accumulator that computes a result of the 
// form: result += object.method();
// all other members same as that of std::accumulate
template <class I, class V, class Fn1, class Fn2>
V accumulate2(I first, I last, V val, Fn1 op, Fn2 memfn) {
    for (; first != last; ++first)
        val = op(val, memfn(*first));
    return val;
}
struct strange {
    strange(int a, int b) : _a(a), _b(b) {}
    int value() { return _a + 10 * _b; }
    int _a, _b;
};
int main() {
    std::vector<strange> dv;
    dv.push_back(strange(1, 3));
    dv.push_back(strange(4, 6));
    dv.push_back(strange(20, -11));        
    cout << accumulate2(dv.begin(), dv.end(), 
                        0, std::plus<int>(), 
                        mem_fun_ref(&strange::value)) << endl;
}
Of course, the original solution still holds:
The easiest is to implement an operator+. In this case:
double operator+(double v, Object const& x) {
        return v + x.a_;
}
and make it a friend of Object or member (look up why you may prefer one over the other):
class Object
{
   //...
  friend double operator+(double v, Object const& x);
and you're done with:
 result = accumulate(collection.begin(), collection.end(), 0.0);
My earlier approach doesn't work because we need a binary_function.
std::accumulate manual.
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