Il modo più semplice che viene in mente è quello di iniziare con la creazione di un tipo di tag e di una singola istanza di esso:
struct JsonStreamTag {} json;
Allora un tale tag costruire un oggetto di avvolgere il flusso:
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;
};
Il costruttore è protected
per garantire che è possibile utilizzare solo some_ostream << json
(1) per creare un JsonStream
. L'altro operatore di inserimento (2) esegue la formattazione effettiva. È quindi definire un sovraccarico di write_json()
(3) per ogni tipo rilevanti:
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.
In alternativa, omettere (2) e aggiungere sovraccarichi per operator<<(JsonStream&, T)
invece.
Quindi basta seguire la stessa procedura per scrivere il corrispondente XmlStream
utilizzando XmlStreamTag
e write_xml()
. Questo presume che il tuo output possa essere costruito completamente dai valori particolari che stai scrivendo; se avete bisogno di un po 'di intestazione o piè di pagina che è la stessa attraverso ogni file potrai scrivere, basta utilizzare il costruttore e distruttore:
XmlStream(std::ostream& ostream) : ostream(ostream) {
ostream << "<?xml version=\"1.0\"?><my_document>"
}
~XmlStream() {
ostream << "</my_document>";
}
fonte
2012-03-09 07:22:39
Non penso che questa sia una buona idea. Non funziona per cose come 'out << json <<" Intestazione: "<< obj;' per esempio. (Naturalmente, per qualcosa come XML, questo non avrebbe comunque senso. Ma questo è un argomento per non usare i manipolatori in primo luogo.) –
@JamesKanze: La domanda non è chiaramente definita. Allo scopo di rispondere letteralmente alla domanda, ho ipotizzato che uno "stream JSON" avrebbe trattato tutto come un valore JSON. Ma penso che una cosa del genere sia sbagliata in primo luogo. –
XML (e JSON, per quanto ne so) non sono flussi; sono strutture più complesse. Un tipo non correlato non deve generare XML o JSON su un 'ostream'; dovrebbe inserirlo in qualche istanza di una struttura dati XML o JSON, che quindi si occuperebbe dell'output in streaming, a livello di file. –