Elegant output separators
That's fine as far as it goes.
Though I am not sure why you want all the added complexity for a problem that seems to be already solved.

What I think we all want is to stream containers in a logical way, that is consistent across containers.

Your basic example:

for(auto const&amp; el: c) {
    std::cout &lt;&lt; sep() &lt;&lt; el;
std::cout &lt;&lt; "\n";


This is a specialization of how I would want containers to be stremed:

auto sep = one_off("", sepObject);
stream &lt;&lt; beginMarker;
for(auto const&amp; el: c) {
    stream &lt;&lt; sep() &lt;&lt; el;
stream &lt;&lt; endMarker;


So for example:

// An array looks like this:
[ 1, 2, 3, 4, 5, 6 ]        // Note terminator is "]\n"

// A map look like this:
{ a =&gt; b, c =&gt; d, e =&gt; f }


So would it be not more logical to define a container streamer object.

std::Container  c = {1,2,3,4,5};
ContainerStream(std::cout) &lt;&lt; c;


Then you can use traits to define the beginMarker, endMarker and sepObject.

Or alternatively rather than wrapping the stream we could potentially wrap the container in something that knows how to print it (and generalize that).

std::cout &lt;&lt; jsonExport(c);