如何让输出流稍后执行某些操作

How do I make an output stream do something later?

本文关键字:执行 操作 输出流      更新时间:2023-10-16

我想让输出流稍后打印一些东西。我想让它像这样工作:

cout << printThisLater("Hello, World") << x << y << printItNow();

我希望流记住我传递给它的字符串。我该怎么做?

这是我尝试过的,但没有奏效:

#include <iostream>
#include <string>
std::string msg;
std::ostream& printThisLater(std::string str)
{
    msg = str;
    return // ??
}
std::string printItNow()
{
    return msg;
}
int main()
{
    int x = 10, y = 59;
    std::cout << printThisLater("Hello World") << x << y << printItNow();
}
您只需将

以后要打印的数据附加到流中,并在需要时检索它。这是如何完成的:

#include <iostream>
#include <string>
class print_this_later {
    std::string value;
public:
    print_this_later(std::string const& value): value(value) {}
    std::string const& str() const { return this->value; }
    static int index() {
        static int rc = std::ios_base::xalloc(); return rc;
    }
    static void erase(std::ios_base::event ev, std::ios_base& ios, int index) {
        if (ev == std::ios_base::erase_event) {
            delete static_cast<std::string*>(ios.pword(index));
        }
    }
};
std::ostream& operator<< (std::ostream& out, print_this_later const& value) {
    void*& pword(out.pword(value.index()));
    if (pword) {
        std::unique_ptr<std::string> tmp(static_cast<std::string*>(pword));
        pword = 0;
        pword = new std::string(*tmp + value.str());
    }
    else {
        out.register_callback(&print_this_later::erase, value.index());
        pword = new std::string(value.str());
    }
    return out;
}
std::ostream& print_now(std::ostream& out) {
    return out << *static_cast<std::string*>(out.pword(print_this_later::index()));
}
int main()
{
    std::cout << print_this_later("world")
              << print_this_later("!")
              << "hello" << ", " << print_now << 'n';
}

基本思想是,print_this_later(string)是一个对象,当string"写入"到流时,它与流一起存储。该值存储在pword()条目中:与

out.pword(index)

您可以访问与索引index下的out关联的void*&。最初,该值将为 null,并将保留上次获取的值。由于只能存储一个void*,因此对象被分配到堆上,需要清理。清理可以通过已注册的回调来完成,该回调在流被销毁时调用。

你为什么不直接使用std::cout默认情况下它是缓冲的,因此,在您在其上放置std::flushstd::endl或程序终止之前,它不会打印任何内容。

如果这对您不起作用,我会使用std::stringstream来缓冲我的文本并写入

std::cout << ss.str() << std::flush;

当您需要实际输出时。