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

时间:2013-12-26 17:58:43

标签: c++ c++11

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

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();
}

2 个答案:

答案 0 :(得分:4)

您可以稍后将要打印的数据附加到流中,并在需要时将其检索。以下是如何做到这一点:

#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)

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

答案 1 :(得分:0)

为什么不使用std::cout默认情况下它是缓冲的,因此如果在它上面放置std::flushstd::endl或程序终止时它将不会打印任何内容。

<击>

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

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

当你想要实际输出时。