Cách đơn giản nhất mà đến với tâm là bắt đầu bằng cách tạo ra một loại thẻ và một trường hợp duy nhất của chúng:
struct JsonStreamTag {} json;
Sau đó, chúng ta hãy một thẻ như xây dựng một đối tượng để bọc các dòng:
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;
};
Nhà xây dựng là protected
để đảm bảo rằng bạn chỉ có thể sử dụng some_ostream << json
(1) để xây dựng JsonStream
. Toán tử chèn khác (2) thực hiện định dạng thực tế. sau đó bạn xác định một tình trạng quá tải của write_json()
(3) cho tất cả các loại có liên quan:
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.
Ngoài ra, bỏ qua (2) và thêm quá tải cho operator<<(JsonStream&, T)
để thay thế.
Sau đó, chỉ cần làm theo quy trình tương tự để viết XmlStream
tương ứng bằng cách sử dụng XmlStreamTag
và write_xml()
. Điều này giả định rằng đầu ra của bạn có thể được xây dựng hoàn toàn từ các giá trị cụ thể mà bạn đang viết; nếu bạn cần một số header hay footer đó là giống nhau trên tất cả các tập tin bạn sẽ viết, chỉ cần sử dụng constructor và destructor:
XmlStream(std::ostream& ostream) : ostream(ostream) {
ostream << "<?xml version=\"1.0\"?><my_document>"
}
~XmlStream() {
ostream << "</my_document>";
}
Nguồn
2012-03-09 07:22:39
Tôi không nghĩ rằng đây là một ý tưởng hay. Nó không hoạt động với những thứ như 'out << json <<" Tiêu đề: "<< obj;' chẳng hạn. (Tất nhiên, đối với một cái gì đó như XML, điều này sẽ không có ý nghĩa anyway. Nhưng đó là một đối số cho không sử dụng thao tác ở nơi đầu tiên.) –
@JamesKanze: Câu hỏi không được xác định rõ ràng. Với mục đích trả lời câu hỏi theo nghĩa đen, tôi đã giả thiết rằng một “luồng JSON” sẽ coi mọi thứ như một giá trị JSON. Nhưng tôi nghĩ rằng một điều như vậy là sai lầm ngay từ đầu. –
XML (và JSON, theo như tôi biết) không phải là luồng; chúng là những cấu trúc phức tạp hơn. Một loại không liên quan không được xuất XML hoặc JSON thành 'ostream'; nó sẽ chèn nó vào một số ví dụ của một cấu trúc dữ liệu XML hoặc JSON, sau đó sẽ xử lý đầu ra được truyền trực tiếp, ở mức tệp. –