检查是否在std :: ostream中序列化了某些内容

时间:2013-07-26 23:38:56

标签: c++ stl ostream

是否有一种简单的方法可以检查某些内容是否已在stl :: ostream中序列化。我正在寻找类似的东西:

some preparation

// ... a very complex code that may result in adding or not to the stream,
// that I will prefer not to change

check if the stream has something added

请注意,这需要以递归方式工作。使用register_callback是个好主意还是有更简单的方法?

2 个答案:

答案 0 :(得分:3)

首先是当前问题:register_callback()旨在处理pword()中存储的资源的适当复制和释放,并且只会执行与此相关的操作(即复制,分配和释放以及观察std::locale更改)。所以,不,这根本不会帮助你。

然而,你可以做的是创建一个过滤流缓冲区,观察是否有对该流的写入,例如:

class changedbuf: std::streambuf {
    std::streambuf* d_sbuf;
    bool            d_changed;
    int_type overflow(int_type c) {
         if (!traits_type::eq_int_type(c, traits_type::eof())) {
             this->d_changed = true;
         }
         return this->d_sbuf->sputc(c);
    }
public:
    changedbuf(std::streambuf* sbuf): d_sbuf(d_sbuf), d_changed() {}
    bool changed() const { return this->d_changed; }
}

您可以使用此代替您已有的std::ostream,例如:

void f(std::ostream& out) {
    changedbuf   changedbuf(out.rdbuf());
    std::ostream changedout(&changedbuf);
    // use changedout instead of out; if you need to use a global objects, you'd
    // replace/restore the used stream buffer using the version of rdbuf() taking
    // an argument
    if (changedbuf.change()) {
        std::cout << "there was a change\n";
    }
}

实际实现实际上将提供缓冲区并处理适当的刷新(即,覆盖sync())和序列输出(即,覆盖xsputn())。但是,上述版本足以作为概念验证。

其他人可能建议使用std::ostringstream。根据写入的数据量,这很容易成为一种性能损失,特别是与适当处理缓冲的高级版changedbuf相比。

答案 1 :(得分:0)

您是将流传递到复杂代码中,还是全局可见?可以是任何类型的ostream,还是可以将类型约束为ofstreamostringstream

如果您的ostream类型支持(例如大多数tellp s),您可以使用fstream来确定自准备代码以来文件位置是否已更改。或者,如果您正在传入流,则可以传入空ostringstream并在提取字符串以将其打印出来时检查它是否为空。

如果不了解代码的上下文和问题的具体细节,哪种解决方案(如果有的话)适合您并不完全明显。最佳答案可能是返回(或设置为按引用输出参数)一个标志,指示是否插入了流。