La forma más simple que viene a la mente es comenzar mediante la creación de un tipo de etiqueta y una única instancia de los mismos:
struct JsonStreamTag {} json;
continuación, vamos a una etiqueta tal construcción de un objeto a envolver la corriente:
class JsonStream {
public:
// (1)
friend JsonStream operator<<(std::ostream& ostream, const JsonStreamTag&) {
return JsonStream(ostream);
}
// (2)
template<class T>
friend JsonStream& operator<<(JsonStream& json_stream, const T& value) {
write_json(json_stream.ostream, value); // (3)
return json_stream;
}
protected:
JsonStream(std::ostream& ostream) : ostream(ostream) {}
private:
std::ostream& ostream;
};
El constructor es protected
para asegurarse de que solo puede usar some_ostream << json
(1) para construir un JsonStream
. El otro operador de inserción (2) realiza el formateo real. A continuación se define una sobrecarga de write_json()
(3) para cada tipo relevante:
void write_json(std::ostream& stream, int value) {
stream << value;
}
void write_json(std::ostream& stream, std::string value) {
stream << '"' << escape_json(value) << '"';
}
// Overloads for double, std::vector, std::map, &c.
Alternativamente, omitir (2) y añadir sobrecargas de operator<<(JsonStream&, T)
lugar.
Luego solo siga el mismo proceso para escribir el XmlStream
correspondiente usando XmlStreamTag
y write_xml()
. Esto supone que su salida puede construirse completamente a partir de los valores particulares que está escribiendo; si necesitas algo de encabezado o pie de página que es el mismo en todos los archivos que voy a escribir, sólo tiene que utilizar el constructor y el destructor:
XmlStream(std::ostream& ostream) : ostream(ostream) {
ostream << "<?xml version=\"1.0\"?><my_document>"
}
~XmlStream() {
ostream << "</my_document>";
}
No creo que esta sea una muy buena idea. No funciona para cosas como 'out << json <<" Encabezado: "<< obj;' por ejemplo. (Por supuesto, para algo como XML, esto no tendría sentido de todos modos. Pero ese es un argumento para no usar manipuladores en primer lugar.) –
@JamesKanze: La pregunta no está claramente definida. Para los propósitos de responder la pregunta literalmente, asumí que una "secuencia JSON" trataría todo como un valor JSON. Pero creo que tal cosa está mal dirigida en primer lugar. –
XML (y JSON, hasta donde yo sé) no son transmisiones; son estructuras más complejas. Un tipo no relacionado no debe generar XML o JSON en un 'ostream'; debe insertarlo en alguna instancia de una estructura de datos XML o JSON, que luego se encargaría de la salida transmitida, a nivel de archivo. –