Best syntax for executing an action between each loop iteration. The question of the cleanest way to write a loop that executes some action between each iteration has always interested me.

In a sense, what is the best way in c/c++ to implement this fictional construct:

for (...) {
} between {
}


Using such a construct you could trivially implement string join(): (pseudocode)

result = "";
foreach ( item : input ) {
    result += str(item);
} between {
    result += sep;
}


I have looked through some popular code libraries to see how these types of loops are implemented, and there are some common strategies:


move the "between" code into an "if (!first/last iteration)" inside the loop.

This is the go-to method when the index/iterator/result freely stores the notion of first/last iteration (such as checks for values of 0, .empty(), NULL etc).

transform the "loop body" into a function and call it from two places: before and during the loop, and change the loop to skip the first element. (minor code duplication)

This is the go-to method when the "loop body" is a single function call



Neither of these is a completely generalized solution, and while its only a few lines + a state variable, I'm trying to find an ideal solution.

Priorities:


No needless source code duplication (but willing to accept binary code duplication)
Efficiency
Clear semantics
Trivially usable (aka simple syntax, few library requirements)
The closest I've come to this in C or C++ is a slight modification to Knuth's loop-and-a-half:

template&lt;class T&gt;
void print(std::vector&lt;T&gt; const &amp;x) {
  std::cout &lt;&lt; '[';
  typename std::vector&lt;T&gt;::const_iterator
    begin = x.begin(),
    end = x.end();
  if (begin != end) {  // Duplicated condition to handle the empty case.
    while (true) {  // Here is the "loop and a half".
      std::cout &lt;&lt; *begin;
      if (++begin == end) break;
      std::cout &lt;&lt; ", ";
    }
  }
  std::cout &lt;&lt; "]\n";
}


C++0x allows you to generalize:

template&lt;class Iter, class Body, class Between&gt;
void foreach(Iter begin, Iter end, Body body, Between between) {
  if (begin != end) {  // This duplication doesn't matter as it is
                       // wrapped up in a library function.
    while (true) {
      body(*begin);
      if (++begin == end) break;
      between();
    }
  }
}

template&lt;class T&gt;
void print(std::vector&lt;T&gt; const &amp;x) {
  std::cout &lt;&lt; '[';
  foreach(x.begin(), x.end(),
    [](T const&amp; v) {
      std::cout &lt;&lt; v;
      // Long code here is still readable.
    },
    []{
      std::cout &lt;&lt; ", ";
      // Long code here is still readable.
    });
  std::cout &lt;&lt; "]\n";
}


Lambda capture even allows you to modify local variables in the function calling foreach.