patterncppMajor
infix_iterator code
Viewed 0 times
codeinfix_iteratorstackoverflow
Problem
I've previously posted this on Stack Overflow, and am considering submitting it to Boost for wider distribution, but thought perhaps it would be best to put it up here for peer review first, and see whether there are clear improvements that can be made first.
This is (at least intended to be) pretty much a drop-in replacement for
The motivation for this is pretty simple -- with a
// infix_iterator.h
//
#if !defined(INFIX_ITERATOR_H_)
#define INFIX_ITERATOR_H_
#include
#include
template >
class infix_ostream_iterator :
public std::iterator
{
std::basic_ostream *os;
charT const* delimiter;
bool first_elem;
public:
typedef charT char_type;
typedef traits traits_type;
typedef std::basic_ostream ostream_type;
infix_ostream_iterator(ostream_type& s)
: os(&s),delimiter(0), first_elem(true)
{}
infix_ostream_iterator(ostream_type& s, charT const *d)
: os(&s),delimiter(d), first_elem(true)
{}
infix_ostream_iterator& operator=(T const &item)
{
// Here's the only real change from ostream_iterator:
// We don't print the delimiter the first time. After that,
// each invocation prints the delimiter *before* the item, not
// after. As a result, we only get delimiters *between* items,
// not after every one.
if (!first_elem && delimiter != 0)
*os &operator*() {
return *this;
}
infix_ostream_iterator &operator++() {
return *this;
}
infix_ostream_iterator &operator++(int) {
return *this;
}
};
#endifThis is (at least intended to be) pretty much a drop-in replacement for
std::ostream_iterator, the sole difference being that (at least in normal use) it only prints out delimiters between items instead of after every item. Code using it looks something like:#include "infix_iterator.h"
std::vector numbers = {1, 2, 3, 4};
std::copy(begin(numbers), end(numbers),
infix_ostream_iterator(std::cout, ", "));The motivation for this is pretty simple -- with a
std::ostream_iterator, your list would coSolution
Nothing major (just some personal opinion ones):
Consistent Spacing
Consistent type Naming
Spelling of
I mistypes it a lot when writing this =>
Easier to read initializer list
Just like I prefer one statement per line, I prefer one variable initialized per line in the initializer list (easier to read).
Remove the if from the main body.
It probably makes no difference to performance, but I would remove the
On construction
Consistent Spacing
infix_ostream_iterator(ostream_type& s)
: os(&s),delimiter(0), first_elem(true)
{} // ^^^ No Space ^^^Trailing spaceConsistent type Naming
// Here we have & on the left
infix_ostream_iterator& operator=(T const &item)
// Here we have it on the right
infix_ostream_iterator &operator*() {Spelling of
delimterI mistypes it a lot when writing this =>
delimiterEasier to read initializer list
Just like I prefer one statement per line, I prefer one variable initialized per line in the initializer list (easier to read).
infix_ostream_iterator(ostream_type& s, charT const *d)
: os(&s)
, delimiter(d)
, first_elem(true)
{}Remove the if from the main body.
It probably makes no difference to performance, but I would remove the
if so the code looks like this:*os << delimter << item;
delimter = actualDelimter;
return *this;On construction
actualDelimter points at the string provided by the user (or empty string) and delimter is set to point at an empty string.Code Snippets
infix_ostream_iterator(ostream_type& s)
: os(&s),delimiter(0), first_elem(true)
{} // ^^^ No Space ^^^Trailing space// Here we have & on the left
infix_ostream_iterator<T,charT,traits>& operator=(T const &item)
// Here we have it on the right
infix_ostream_iterator<T,charT,traits> &operator*() {infix_ostream_iterator(ostream_type& s, charT const *d)
: os(&s)
, delimiter(d)
, first_elem(true)
{}*os << delimter << item;
delimter = actualDelimter;
return *this;Context
StackExchange Code Review Q#13176, answer score: 25
Revisions (0)
No revisions yet.