Comma-formatted STL vectors I move back and forth between Python and C++ and I often need a nice/quick way to output STL objects to the screen for debugging purposes. I'd like the output to match the output of a comparable Python object, thus I have different templates for vectors, sets, etc...

Is this the best way to go about this?

template &lt;class T&gt;
ostream&amp; operator&lt;&lt;(ostream&amp; s, const vector&lt;T&gt; &amp;A) {
  if(A.empty()) 
    return s &lt;&lt; "[]";

  s &lt;&lt; "[";
  typename vector&lt;T&gt;::const_iterator itr_penultimate = --A.end();
  typename vector&lt;T&gt;::const_iterator itr = A.begin();

  while(itr != itr_penultimate) {
    s &lt;&lt; *itr &lt;&lt; ", ";
    itr++;
  }
  return s &lt;&lt; *itr &lt;&lt; "]";
}
The above answer is fine.

The only problem I have is the extra ',' in the output:

std::cout &lt;&lt; "[ ";
std::copy(data.begin(), data.end(), std::ostream_iterator&lt;int&gt;(std::cout, ", "));
std::cout &lt;&lt; " ]\n";


Generates the output:

[ 1, 2, 3, 4, 5, 6,  ]
                  ^  extra comma


You can get around this with some extra work.

auto end = data.end();
if (!data.empty()) { --end;}
std::cout &lt;&lt; "[ ";
std::copy(data.begin(), end, std::ostream_iterator&lt;int&gt;(std::cout, ", "));
if (!data.empty()) {std::cout &lt;&lt; *end;}
std::cout &lt;&lt; " ]\n";


Generates the output:

[ 1, 2, 3, 4, 5, 6 ]


This is better but it sort of defeats the purpose of using algorithms.

If we had used the loop it would look like this:

std::cout &lt;&lt; "[";
for(auto loop = data.begin(); loop != data.end(); ++loop)
{
     std::cout &lt;&lt; *itr &lt;&lt; ", ";
}
std::cout &lt;&lt; "]";


Of course this has the same problem as the first version of the algorithm above. So if we take that into account you can re-write like this:

std::cout &lt;&lt; "[";
auto begin = data.begin();
if (!data.empty) {std::cout &lt;&lt; *begin;++begin}
for(auto loop = begin; loop != data.end(); ++loop)
{
     std::cout &lt;&lt; ", " &lt;&lt; *loop;
}
std::cout &lt;&lt; "]";


Now it works. And because it only use one test on empty is better than the altered algorithm version in my opinion. So what we really need is a version of the output iterator that does the above.

template&lt;typename T&gt;
class PrefexOutputIterator
{
    std::ostream&amp;       ostream;
    std::string         prefix;
    bool                first;
    public:

    typedef std::size_t                 difference_type;
    typedef T                           value_type;
    typedef T*                          pointer;
    typedef T                           reference;
    typedef std::output_iterator_tag    iterator_category;

        PrefexOutputIterator(std::ostream&amp; o,std::string const&amp; p = ""): ostream(o), prefix(p), first(true) {}

        PrefexOutputIterator&amp; operator*()       {return *this;}
        PrefexOutputIterator&amp; operator++()      {return *this;}
        PrefexOutputIterator&amp; operator++(int)   {return *this;}

        void operator=(T const&amp; value)
        {
            if (first)      {ostream &lt;&lt; value;first = false;}
            else            {ostream &lt;&lt; prefix &lt;&lt; value;}
        }
};


Now we can use this and get the output we want:

std::cout &lt;&lt; "[";
std::copy(data.begin(), data.end(), PrefexOutputIterator&lt;int&gt;(std::cout, ", "));
std::cout &lt;&lt; "]";


The output is:

[1, 2, 3, 4, 5, 6]


Nowadays though I seem to be using a lot of Json.
So now I use this template librrys: https://github.com/Loki-Astari/ThorsSerializer

using ThorsAnvil::Serialize::jsonExport;
using ThorsAnvil::Serialize::jsonImport;

std::cout &lt;&lt; jsonExport(data) &lt;&lt; "\n"; // Serialize the array as json (looks like above)
std::cin  &gt;&gt; jsonImport(data);         // Reads a json array into an array.