operador de sobrecarga << para std :: tuple - ¿posibles simplificaciones?

Solía una respuesta a la pregunta SO "iterar sobre tupla" para escribir un método para sobrecargar<<. Este método fue probado y parece funcionar correctamente cong++ 4.7 en Debian squeeze.

Sin embargo, este método es un poco indirecto, ya que parece<< no se puede crear una instancia explícita (encontré una publicación al respectoaqu). Entonces, uno se ve obligado a definir un método de cadena y luego llamarlo. Tengo un método similar para vector, que es más directo. ¿Alguien tiene sugerencias sobre cómo eliminar el paso adicional de crear un método de cadena, utilizando el mismo enfoque o de otra manera? Gracias por adelantado

#include <tuple>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>

using std::ostream;
using std::cout;
using std::endl;
using std::vector;
using std::string;

// Print vector<T>.
template<typename T> ostream& operator <<(ostream& out, const vector<T> & vec)
{
  unsigned int i;
  out << "[";
  for(i=0; i<vec.size(); i++)
    {
      out << vec[i];
      if(i < vec.size() - 1)
    out << ", ";
    }
  out << "]";
  return out;
}

////////////////////////////////////////////////////////////////

// Print tuple.
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), string>::type
stringval(const std::tuple<Tp...> & t)
{
  std::stringstream buffer;
  buffer << "]";
  return buffer.str();
}

template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), string>::type
stringval(const std::tuple<Tp...> & t)
{
  std::stringstream buffer;
  size_t len = sizeof...(Tp);
  if(I==0)
      buffer << "[";
  buffer << std::get<I>(t);
  if(I < len - 1)
    buffer << ", ";
  buffer << stringval<I + 1, Tp...>(t);
  return buffer.str();
}

template<typename... Tp> ostream& operator <<(ostream& out, const std::tuple<Tp...> & t)
{
  out << stringval(t);
  return out;
}

int
main()
{
  typedef std::tuple<int, float, double> T;
  std::tuple<int, float, double> t = std::make_tuple(2, 3.14159F, 2345.678);
  cout << t << endl;
}

Cuando se compila, esto da

[2, 3.14159, 2345.68]

Respuestas a la pregunta(8)

Su respuesta a la pregunta