使用std :: accumulate累积到std :: ostream

时间:2016-01-29 08:19:13

标签: c++ c++11 stream operator-overloading ostream

我正在尝试使用std::accumulatestd::ostream中写入operator<<(这只是一个最小的例子,我知道这可以更简单地实现):

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

如何让这个操作符起作用?

4 个答案:

答案 0 :(得分:2)

您可能会滥用此std::accumulate

std::ostream& operator<<(std::ostream& stream, A& a) {
    return std::accumulate(a.v.begin(), a.v.end(), std::ref(stream),
                           [](std::ostream& stream, int e)
                           { return std::ref(stream << " " << e); });
}

Demo

答案 1 :(得分:1)

请勿使用accumulate,请使用copy

std::ostream& operator<<(std::ostream& stream, A& a) {
  std::copy(a.v.begin(), a.v.end(), std::ostream_iterator<int>(stream, " "));
}

这实际上是one of the examples at the above reference page(虽然适用于std::copy,不适用于std::ostream_iterator

答案 2 :(得分:0)

既然你提到for_each也可以使用(并且刚刚提到积累以混淆火星人):

std::ostream& operator<<(std::ostream& stream, const A& a) {
  std::for_each(begin(a.v), end(a.v), [](int i){ std::cout << i << " "; });
  return stream;
}

注意:你在这里有一个尾随空格。如果你想避免这种情况(例如在lambda中使用一个计数器),你需要以不同的方式处理第一个或最后一个元素。

答案 3 :(得分:0)

可以这样做:

// 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是自然的选择,因为你并不太关心累积值。