Can I use accumulate to do this?

Discussion in 'C++' started by Suman, Mar 7, 2009.

  1. Suman

    Suman Guest

    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
     
    Suman, Mar 7, 2009
    #1
    1. Advertising

  2. Suman

    Guest

    On Mar 7, 12:42 pm, Suman <> wrote:
    > 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
     
    , Mar 8, 2009
    #2
    1. Advertising

  3. Suman wrote:

    > 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

    --
    Quidquid latine scriptum est, altum videtur.
     
    Martin Eisenberg, Mar 8, 2009
    #3
  4. Suman

    Suman Guest

    wrote:

    > On Mar 7, 12:42 pm, Suman <> wrote:
    > > 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.
    >


    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
     
    Suman, Mar 8, 2009
    #4
  5. Suman

    dimwit Guest

    On Mar 8, 7:19 pm, Martin Eisenberg <> wrote:
    [...]
    >
    > 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
     
    dimwit, Mar 8, 2009
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Brian K. Michalk

    64 bit add and accumulate with MMX

    Brian K. Michalk, Sep 20, 2003, in forum: Perl
    Replies:
    6
    Views:
    665
    Terje Mathisen
    Sep 20, 2003
  2. Roedy Green

    Accumulate 1.0

    Roedy Green, Jul 17, 2004, in forum: Java
    Replies:
    0
    Views:
    407
    Roedy Green
    Jul 17, 2004
  3. accumulate() usage

    , Feb 2, 2006, in forum: C++
    Replies:
    1
    Views:
    360
    Neelesh Bodas
    Feb 2, 2006
  4. cesco
    Replies:
    5
    Views:
    476
    Maxim Yegorushkin
    Feb 13, 2006
  5. Replies:
    1
    Views:
    1,757
Loading...

Share This Page