title: overloading operator << for std::tuple - possible simplications?
body: <p>I used  <a href="https://stackoverflow.com/a/6894436/350713">an answer to the SO question "iterate over tuple"</a> to write a method to overload <code>&lt;&lt;</code>. This method was tested and appears to work correctly with <code>g++ 4.7</code> on Debian squeeze.</p>
  
  <p>However this method is kind of roundabout, since it seems <code>&lt;&lt;</code> cannot be explicitly instantiated (I found a post about it 
  <a href="https://stackoverflow.com/questions/4038232/how-to-template-for-operator-for-ostream">here</a>). So, one is forced to define a string method and then call that. I have a similar method for vector, which is more direct. Does anyone have suggestions about how to eliminate the extra step of creating a string method, using the same approach, or otherwise? Thanks in advance.</p>
  
  <pre><code>#include &lt;tuple&gt;
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;sstream&gt;
  #include &lt;vector&gt;
  
  using std::ostream;
  using std::cout;
  using std::endl;
  using std::vector;
  using std::string;
  
  // Print vector&lt;T&gt;.
  template&lt;typename T&gt; ostream&amp; operator &lt;&lt;(ostream&amp; out, const vector&lt;T&gt; &amp; vec)
  {
    unsigned int i;
    out &lt;&lt; "[";
    for(i=0; i&lt;vec.size(); i++)
      {
        out &lt;&lt; vec[i];
        if(i &lt; vec.size() - 1)
      out &lt;&lt; ", ";
      }
    out &lt;&lt; "]";
    return out;
  }
  
  ////////////////////////////////////////////////////////////////
  
  // Print tuple.
  template&lt;std::size_t I = 0, typename... Tp&gt;
  inline typename std::enable_if&lt;I == sizeof...(Tp), string&gt;::type
  stringval(const std::tuple&lt;Tp...&gt; &amp; t)
  {
    std::stringstream buffer;
    buffer &lt;&lt; "]";
    return buffer.str();
  }
  
  template&lt;std::size_t I = 0, typename... Tp&gt;
  inline typename std::enable_if&lt;I &lt; sizeof...(Tp), string&gt;::type
  stringval(const std::tuple&lt;Tp...&gt; &amp; t)
  {
    std::stringstream buffer;
    size_t len = sizeof...(Tp);
    if(I==0)
        buffer &lt;&lt; "[";
    buffer &lt;&lt; std::get&lt;I&gt;(t);
    if(I &lt; len - 1)
      buffer &lt;&lt; ", ";
    buffer &lt;&lt; stringval&lt;I + 1, Tp...&gt;(t);
    return buffer.str();
  }
  
  template&lt;typename... Tp&gt; ostream&amp; operator &lt;&lt;(ostream&amp; out, const std::tuple&lt;Tp...&gt; &amp; t)
  {
    out &lt;&lt; stringval(t);
    return out;
  }
  
  int
  main()
  {
    typedef std::tuple&lt;int, float, double&gt; T;
    std::tuple&lt;int, float, double&gt; t = std::make_tuple(2, 3.14159F, 2345.678);
    cout &lt;&lt; t &lt;&lt; endl;
  }
  </code></pre>
  
  <p>When compiled, this gives</p>
  
  <pre><code>[2, 3.14159, 2345.68]
  </code></pre>