The Artima Developer Community
Sponsored Link

Weblogs Forum
A Generic Ostream Iterator

2 replies on 1 page. Most recent reply: Sep 9, 2009 10:26 PM by Jono Pfaff

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 2 replies on 1 page
Christopher Diggins

Posts: 1215
Nickname: cdiggins
Registered: Feb, 2004

A Generic Ostream Iterator (View in Weblogs)
Posted: Nov 11, 2005 7:00 AM
Reply to this message Reply
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.
Advertisement
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"));
}


Elizabeth Wiethoff

Posts: 89
Nickname: ewiethoff
Registered: Mar, 2005

Re: A Generic Ostream Iterator Posted: Nov 29, 2005 9:42 PM
Reply to this message Reply
<pre>
int main() {
int array[] = { 1, 2, 4, 8, 16, 32, 64 };
std::copy(array, array + 7, put(std::cout, "\n"));
}
</pre>

This is starting to look like functional programming in Python. :-) Is your generic ostream iterator in the <i>C++ Cookbook</i>?

Jono Pfaff

Posts: 1
Nickname: shiprat
Registered: Sep, 2009

Re: A Generic Ostream Iterator Posted: Sep 9, 2009 10:26 PM
Reply to this message Reply
Hi,

I liked your generic ostream iterator, but i felt compelled to gild the lily, so this version automatically dereferences pointers. It might not be what everybody wants all the time, but its often what i want a lot of the time!

Jono
Auckland, NZ

struct putter {

template<typename U>
struct Getter{
const U& operator()(const U& u){return u;}
const U& operator()(U*const&){}
};

template<typename U>
struct Getter<U*>{
const U& operator()(U const&){}
const U& operator()(U*const&u){return *u;}
};

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) {
Getter<T> getter;
o << getter(x) << delim; return *this;
}
putter& operator*() { return *this; }
putter& operator++() { return *this; }
putter& operator++(int) { return *this; }
mutable std::ostream& o;
const char* delim;
};

Flat View: This topic has 2 replies on 1 page
Topic: Why? Language Archaeology ... and Metaprogramming Previous Topic   Next Topic Topic: Installing Ubuntu on my MacBook

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use