我正在尝试使用std::accumulate
在std::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;
}
如何让这个操作符起作用?
答案 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); });
}
答案 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
是自然的选择,因为你并不太关心累积值。