Can I use accumulate to do this?

S

Suman

I just can't get my head around to create a suitable
binary_function that will do this i.e. call a member function
from within accumulate. In fact I rolled my own template.
But I have a terrible feeling of reinventing the wheel.

/
*----------------------------------------------------------------------
*/
#include <vector>
#include <iterator>
#include <iostream>

using namespace std;

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;
}

/
*----------------------------------------------------------------------
*/

I have not yet looked into Boost -- but suggestions
are most welcome.

Regards,
Suman
 
J

joecook

I just can't get my head around to create a suitable
binary_function that will do this i.e. call a member function
from within accumulate. In fact I rolled my own template.
But I have a terrible feeling of reinventing the wheel.

It looks like you are really trying to call two functions? Take a
look at std::inner_product.

HTH,
Joe
 
M

Martin Eisenberg

Suman said:
I just can't get my head around to create a suitable
binary_function that will do this i.e. call a member function
from within accumulate. In fact I rolled my own template.
But I have a terrible feeling of reinventing the wheel.

The basic version -- note that I made strange::value() const:

#include <iostream>
#include <vector>
#include <numeric>

struct strange {
strange(int a, int b) : _a(a), _b(b) {}
int value() const { return _a + 10 * _b; }
int _a, _b;
};

struct AddValue {
int operator()(int x, const strange& y) { return x + y.value(); }
};

int main()
{
std::vector<strange> dv;
dv.push_back(strange(1, 3));
dv.push_back(strange(4, 6));
dv.push_back(strange(20, -11));

std::cout << std::accumulate(dv.begin(), dv.end(), 0, AddValue());
std::cout << std::endl;
return 0;
}

And the flashy version:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

//...

using namespace boost::lambda;
std::cout << std::accumulate(dv.begin(), dv.end(), 0,
_1 + bind(&strange::value, _2));


Martin
 
S

Suman

It looks like you are really trying to call two functions? Take a
look at std::inner_product.

I'm not sure I understand. I only have a single vector of `strange`
objects. Maybe, you can help me out with a line of code. Note, I
really wanted to be able to work my way out with accumulate. Of
course, a new trick or two will never go in waster :)

Regards,
Suman
 
D

dimwit

The basic version -- note that I made strange::value() const:

That's a good thing to do -- I missed it.

[...]
struct AddValue {
  int operator()(int x, const strange& y)  { return x + y.value(); }

};

Thanks! I should have mentioned that I already know how
to pass in functors. I was thinking about creating functors
on-the-fly much the way boost does, without using boost. I
ended up realising that bind curries and I'd need something
more powerful to be able to compose functions.
And the flashy version: [...]
  std::cout << std::accumulate(dv.begin(), dv.end(), 0,
                               _1 + bind(&strange::value, _2));

I spent the entire afternoon reading up BLL. I came up with
a slightly heavier version:

std::cout << std::accumulate(dv.begin(), dv.end(), 0,
_1 += bind(&strange::value, _2));

I'll dive deeper and see what goes on under the hoods.

Regards,
Suman
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top