2007-09-07
A Generic Ostream Iterator
关键字: stream
by Christopher Diggins
November 11, 2005
Summary
Ostream iterators are a handy but under-utilized tool for using the STL to output containers and ranges. Here I provide an alternative, which has a more pleasing syntax.
An ostream iterator, allows you to use STL algorithms, such as std::copy to output a container or range to an output stream. A simple example is:
int main() {
int array[] = { 1, 2, 4, 8, 16, 32, 64 };
std::copy(array, array + 7, std::ostream_iterator<int>(std::cout, "\n"));
}
The declaration for an ostream_iterator is clunky because you to know the kind of elements it will be reading. You can make the code more readable as follows:
int main() {
int array[] = { 1, 2, 4, 8, 16, 32, 64 };
typedef std::ostream_iterator<int> oiter;
std::copy(array, array + 7, oiter(std::cout, "\n"));
}
This is still more complex than strictly neccessary. The problem is that the ostream_iterator is a template. An alternative implementation would be to make the operator=() member function a template.
#include <iostream>
struct putter {
putter(const putter& x) : o(x.o), delim(x.delim) { }
putter(std::ostream& x = std::cout, const char* s = "") : o(x), delim(s) { }
template<typename T>
putter& operator=(const T& x) { o << x << delim; return *this; }
putter& operator*() { return *this; }
putter& operator++() { return *this; }
putter& operator++(int) { return *this; }
mutable std::ostream& o;
const char* delim;
};
putter put(std::ostream& o = std::cout, const char* delim = "") {
return putter(o, delim);
}
Now you can output the contents of any iterator pair with less work.
int main() {
int array[] = { 1, 2, 4, 8, 16, 32, 64 };
std::copy(array, array + 7, put(std::cout, "\n"));
}
November 11, 2005
Summary
Ostream iterators are a handy but under-utilized tool for using the STL to output containers and ranges. Here I provide an alternative, which has a more pleasing syntax.
An ostream iterator, allows you to use STL algorithms, such as std::copy to output a container or range to an output stream. A simple example is:
int main() {
int array[] = { 1, 2, 4, 8, 16, 32, 64 };
std::copy(array, array + 7, std::ostream_iterator<int>(std::cout, "\n"));
}
The declaration for an ostream_iterator is clunky because you to know the kind of elements it will be reading. You can make the code more readable as follows:
int main() {
int array[] = { 1, 2, 4, 8, 16, 32, 64 };
typedef std::ostream_iterator<int> oiter;
std::copy(array, array + 7, oiter(std::cout, "\n"));
}
This is still more complex than strictly neccessary. The problem is that the ostream_iterator is a template. An alternative implementation would be to make the operator=() member function a template.
#include <iostream>
struct putter {
putter(const putter& x) : o(x.o), delim(x.delim) { }
putter(std::ostream& x = std::cout, const char* s = "") : o(x), delim(s) { }
template<typename T>
putter& operator=(const T& x) { o << x << delim; return *this; }
putter& operator*() { return *this; }
putter& operator++() { return *this; }
putter& operator++(int) { return *this; }
mutable std::ostream& o;
const char* delim;
};
putter put(std::ostream& o = std::cout, const char* delim = "") {
return putter(o, delim);
}
Now you can output the contents of any iterator pair with less work.
int main() {
int array[] = { 1, 2, 4, 8, 16, 32, 64 };
std::copy(array, array + 7, put(std::cout, "\n"));
}
发表评论
- 浏览: 9942 次
- 性别:

- 来自: 上海

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
站在巨人肩上的思考[连载 ...
呵呵,我看的是Effective C++第三版,第一个item。 对,就是那四句 ...
-- by shi5jin -
站在巨人肩上的思考[连载 ...
欢迎讨论远程数据库和rpc的编程。 “《Effective C++》的开篇点题 ...
-- by bigpanda -
站在巨人肩上的思考 [连载 ...
读完这两节,我基本就一个字,“基本帅呆了”。
-- by spinach -
站在巨人肩上的思考 [连载 ...
终于等到了,慢慢看。
-- by spinach -
站在巨人肩上的思考 [连载 ...
期待下文
-- by spinach






评论排行榜