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

check if something was serialized in std::ostream

本文关键字:是否 std ostream 检查 序列化      更新时间:2023-10-16

有没有一种简单的方法可以检查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是个好主意还是有更简单的方法?

首先是一个直接的问题: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 changen";
    }
}

一个真正的实现实际上将提供一个缓冲区并处理正确的刷新(即,覆盖sync())和序列输出(即,超控xsputn())。然而,上述版本足以作为概念的证明。

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

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

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

在不了解更多代码上下文和问题细节的情况下,哪种解决方案(如果有的话)适合您还不完全清楚。最好的答案可能是返回(或设置为通过引用out参数)指示流是否被插入的标志。

相关文章: