頭に浮かぶ最も簡単な方法は、タグの種類とその単一のインスタンスを作成することにより開始することです:
struct JsonStreamTag {} json;
次に、このようなタグは、ストリームをラップするオブジェクトを作成してみましょう:
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;
};
some_ostream << json
(1)のみを使用してJsonStream
を構築できることを保証するために、コンストラクタはprotected
です。他の挿入演算子(2)は実際の書式設定を行います。 (2)を省略し、代わりにoperator<<(JsonStream&, T)
のためのオーバーロードを追加し、また
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.
:あなたはその後、すべての関連するタイプのために(3)write_json()
のオーバーロードを定義します。
次に、対応するXmlStream
を書き込んで、XmlStreamTag
とwrite_xml()
を使用して、同じプロセスを実行します。これは、あなたが書いている特定の値からあなたの出力を完全に構築できることを前提としています。あなたは簡単に既存の フラグをハイジャックかにstd::ios_base::xalloc
のいずれかを使用して、ヨール独自のマニピュレータを作成することができます
XmlStream(std::ostream& ostream) : ostream(ostream) {
ostream << "<?xml version=\"1.0\"?><my_document>"
}
~XmlStream() {
ostream << "</my_document>";
}
私はこれがとても良いアイデアだとは思わない。 'out << json <<"ヘッダのようなものでは機能しません: "<< obj;" (もちろん、XMLのようなものについては、これはとにかく意味をなさないでしょうが、それはまずマニピュレータを使わないという議論です) –
@JamesKanze:質問は明確に定義されていません。質問に答える目的で、私は「JSONストリーム」がすべてをJSON値として扱うことを前提にしていました。しかし、私はそのようなことが最初に間違っていると思う。 –
XML(JSON、私が知る限り)はストリームではありません。それらはより複雑な構造です。無関係の型はXMLまたはJSONを 'ostream'に出力しません。ファイルレベルでストリーミングされた出力を処理するXMLまたはJSONデータ構造のインスタンスに挿入する必要があります。 –