1

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

4

2 回答 2

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适当处理缓冲的高级版本相比。

于 2013-07-26T23:53:56.417 回答
0

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

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

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

于 2013-07-26T23:51:24.467 回答