Comando simple para combinar un número arbitrario de valores de tipos arbitrarios en una sola cadena

Considere el siguiente código.

int id = 666;
stringstream stream(stringstream::in | stringstream::out);
stream << "Object " << id << " active.";
file.write(stream.str());

Combina muy bien todos los valores precedidos por << en una cadena. Me encantaría descubrir una versión más corta y fácil de usar con menos duplicación de código. Además, el código anterior es solo un ejemplo, y el comando debe aceptar combinaciones arbitrarias de variables y cadenas. Idealmente algo como:

int id = 666;
WRITE("Object ", id, " active.");

¿Es esto posible en C++? de forma portátil, incluso con Boost.Preprocessor, funciones en línea y toda la bolsa de trucos.

preguntado el 28 de agosto de 12 a las 09:08

Creo que debe ser más específico, ya que tal como está, debería poder envolver el código original en una función llamada WRITE. -

¿Podrías hacer tu WRITE algo como printf con el ... ¿concepto? -

Entonces, ¿solo quiere poner un número arbitrario de valores de tipos diferentes en el archivo? Podrías probar con una plantilla variada. -

Me disculpo por la pregunta muy poco clara. Intenté mejorarlo, aclarando que necesito un número variable de argumentos y que no es obligatorio usar stringstream. -

A std::stringstream está abierto para lectura y escritura por defecto, no hay necesidad de construirlo con (stringstream::in | stringstream::out) -

3 Respuestas

Puede lograr esto sin verificar el tipo usando una macro:

//filewrite.h
#define WRITE(first, second, third) \
{\
   stringstream stream(stringstream::in | stringstream::out);\
   stream << first << second << third;\
   file.write(stream.str());\
}

O, más limpio, con una función de plantilla:

template<typename T1, typename T2, typename T3>
void WRITE(T1 const& first, T2 const& second, T3 const& third, fstream& file)
{
   stringstream stream(stringstream::in | stringstream::out);
   stream << first << second << third;
   file.write(stream.str());
}

Respondido 28 ago 12, 10:08

dado el título, creo que la intención es hacerlo sin verificación de tipos, por lo tanto, no hay tipos específicos en los parámetros de su función: MartyE

Ahora, ¿alguna forma de extenderlo para tomar un número ilimitado de requisitos? - MartyE

@MartyE podría usar varargs, pero no tengo tiempo para verificar la sintaxis en este momento. - Luciano Grigore

Al usar una macro, también se pueden usar fácilmente parámetros ilimitados si el (x << y << z) La notación se puede utilizar en el código de usuario. - Stefaanv

Los últimos dos comentarios bien podrían ser las dos respuestas correctas a mi consulta. ¡Los revisaré! - Vorac

Si realmente no desea la verificación de tipos, no use C ++, ¡es un lenguaje de tipado estático!

Si solo quiere decir que quiere que funcione para cualquier tipo, use una macro (eurgh) o usar plantillas variadas, algo como https://gitlab.com/redistd/redistd/blob/master/include/redi/printers.h que soporta:

#include <redi/printers.h>
using redi::println;
int main()
{
  int id = 666;
  println("Object ", id, " active.");  // write arguments to stdout
}

El println función toma cualquier número de argumentos y fue descaradamente robado de inspirado en un código de ejemplo de Howard Hinant.

Sería bastante fácil adaptar eso para escribir a un fstream en lugar de std::cout por ejemplo, agregando

inline
void
fprintln()
{ file << std::endl; }

template<typename T0, typename... T>
  inline
  void
  fprintln(const T0& t0, const T&... t)
  {
    print_one(file, t0);
    fprintln(t...);
  }

Entonces:

 fprintln("Object ", id, " active.");  // write arguments to 'file'

contestado el 23 de mayo de 17 a las 13:05

No necesitas (ni quieres) macros. Para esto se diseñaron las plantillas:

template <typename T>
void
write( std::string const& prefix, T const& value, std::string const& suffix )
{
    std::ostringstream fmt;
    fmt << prefix << value << suffix;
    file.write( fmt.str() );
}

Por otro lado, ¿por qué molestarse? ¿Por qué no dejar que el código del cliente use el lenguaje idiomático?

file << prefix << value << suffix;

Respondido 28 ago 12, 10:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.