Search code examples
c++c++11streamoperator-overloadingostream

Accumulating into std::ostream using std::accumulate


I am trying to use std::accumulate to write into std::ostream in the operator<< (this is just a minimum example, I know this could be implemented much simpler):

#include <iterator>
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>

struct A {
    A() : v(std::vector<int>()){};
    std::vector<int> v;
    A(std::vector<int> v) : v(v){};
    friend std::ostream& operator<<(std::ostream& stream, A& a);
};

std::ostream& operator<<(std::ostream& stream, A& a) {
// I need something similar to
//    return std::accumulate(a.v.begin(), a.v.end(), "",
                           std::ostream_iterator<int>(stream, " "));
// or:
// return std::accumulate(a.v.begin(), a.v.end(), stream,
                           []()->{});
}

int main(int argc, char* argv[]) {
    std::vector<int> v({1, 2, 3, 4, 5});
    A a(v);
    std::cout << a << std::endl;

    return 0;
}

How can I make this operator work?


Solution

  • It can be done:

    // Using accumulate
    std::ostream& out_acc(const std::vector<int>& is, std::ostream& out)
    {
        return std::accumulate(is.begin(),
                               is.end(),
                               std::ref(out),
                               [](std::ostream& os, int i) -> std::ostream&
                               { return os << i << ", "; });
    
    }
    
    // Using for_each
    std::ostream& out_for(const std::vector<int>& is, std::ostream& out)
    {
        std::for_each(is.begin(),
                        is.end(),
                        [&](int i)
                        { out << i << ", "; });
        return out;
    
    }
    

    for_each is the natural choice, as you don't really care much about the accumulated value.