std :: flush如何工作? [英] How does std::flush work?

查看:833
本文介绍了std :: flush如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以解释(最好使用纯英文) std :: flush 如何工作?

Can someone please explain (preferably using plain english) how std::flush works?

    $ b
  • 是什么?

  • 什么时候可以刷新信息流?

  • b
  • What is it?
  • When would you flush a stream?
  • Why is it important?

谢谢。

推荐答案

std :: flush 恰好是,这里是一些细节,实际上是什么。 std :: flush 是一个操纵符,即具有特定签名的函数。从简单的开始,你可以想到有

Since it wasn't answered what std::flush happens to be, here is some detail on what it actually is. std::flush is a manipulator, i.e., a function with a specific signature. To start off simple, you can think of std::flush of having the signature

std::ostream& std::flush(std::ostream&);

现实情况有点复杂,但如果你有兴趣, )。

The reality is a bit more complex, though (if you are interested, it is explained below as well).

流类重载输出操作符接受这种形式的操作符,即有一个成员函数使用操纵器作为参数。输出操作符使用对象本身调用操纵器:

The stream class overload output operators taking operators of this form, i.e., there is a member function taking a manipulator as argument. The output operator calls the manipulator with the object itself:

std::ostream& std::ostream::operator<< (std::ostream& (*manip)(std::ostream&)) {
    (*manip)(*this);
    return *this;
}

也就是说,当你输出 std: :flush std :: ostream ,它只是调用相应的函数,即下面的两个语句是等效的:

That is, when you "output" std::flush with to an std::ostream, it just calls the corresponding function, i.e., the following two statements are equivalent:

std::cout << std::flush;
std::flush(std::cout);

现在, std :: flush()它本身是相当简单:它所做的是调用 std :: ostream :: flush(),即,你可以设想其实现看起来像这样:

Now, std::flush() itself is fairly simple: All it does is to call std::ostream::flush(), i.e., you can envision its implementation to look something like this:

std::ostream& std::flush(std::ostream& out) {
    out.flush();
    return out;
}

std :: ostream :: flush 函数在与流相关联的流缓冲区(如果有)上技术上调用 std :: streambuf :: pubsync():流缓冲区负责缓冲字符并在使用的缓冲区溢出时或当内部表示应与外部目的地同步时,即当数据要被刷新时向外部目的地发送字符。在与外部目的地同步的顺序流只是意味着立即发送任何缓冲的字符。也就是说,使用 std :: flush 会导致流缓冲区刷新其输出缓冲区。例如,当数据写入控制台时,刷新会导致字符在控制台上出现。

The std::ostream::flush() function technically calls std::streambuf::pubsync() on the stream buffer (if any) which is associated with the stream: The stream buffer is responsible for buffering characters and sending characters to the external destination when the used buffer would overflow or when the internal representation should be synced with the external destination, i.e., when the data is to be flushed. On a sequential stream syncing with the external destination just means that any buffered characters are immediately sent. That is, using std::flush causes the stream buffer to flush its output buffer. For example, when data is written to a console flushing causes the characters to appear at this point on the console.

这可能会引发一个问题:为什么不立即书面?简单的答案是,写字符通常相当慢。然而,写入合理数量的字符所花费的时间基本上等同于在其中仅写入一个字符。字符的数量取决于操作系统,文件系统等的许多特性,但通常达到类似4k字符的大约相同的时间被写入只有一个字符。因此,在根据外部目的地的细节使用缓冲器发送它们之前缓冲字符可以是巨大的性能改进。

This may raise the question: Why aren't characters immediately written? The simple answer is that writing characters is generally fairly slow. However, the amount of time it takes to write a reasonable amount of characters is essentially identical to writing just one where. The amount of characters depends on many characteristics of the operating system, file systems, etc. but often up to something like 4k characters are written in about the same time as just one character. Thus, buffering characters up before sending them using a buffer depending on the details of the external destination can be a huge performance improvement.

上述应该回答你的三个问题中的两个。剩下的问题是:什么时候刷新流?答案是:当字符应该写到外部目的地!这可能是在写入文件(关闭文件隐式刷新缓冲区,尽管)或在请求用户输入之前(请注意, std :: cout 是自动当从 std :: cin 读取 std :: cout 时,刷新 std :: istream :: tie()'d到 std :: cin )。虽然可能有几次你明确想要刷新流,我发现它们是相当罕见的。

The above should answer two of your three questions. The remaining question is: When would you flush a stream? The answer is: When the characters should be written to the external destination! This may be at the end of writing a file (closing a file implicitly flushes the buffer, though) or immediately before asking for user input (note that std::cout is automatically flushed when reading from std::cin as std::cout is std::istream::tie()'d to std::cin). Although there may be a few occasions where you explicitly want to flush a stream, I find them to be fairly rare.

最后,我答应给出一个完整的图片 std :: flush 实际上是:流是类模板能够处理不同的字符类型(实际上他们使用 char wchar_t ;使它们与另一个字符工作是相当参与,虽然如果你真的确定可行)。为了能够在流的所有实例化中使用 std :: flush ,它恰好是一个具有如下签名的函数模板:

Finally, I promised to give a full picture of what std::flush actually is: The streams are class templates capable of dealing with different character types (in practice they work with char and wchar_t; making them work with another characters is quite involved although doable if you are really determined). To be able to use std::flush with all instantiations of streams, it happens to be a function template with a signature like this:

template <typename cT, typename Traits>
std::basic_ostream<cT, Traits>& std::flush(std::basic_ostream<cT, Traits>&);

立即使用 std :: flush 实例化 std :: basic_ostream 它没有真正重要:编译器自动推断模板参数。但是,如果这个函数没有一起提及,有助于模板参数推导,编译器将无法推导模板参数。

When using std::flush immediately with an instantiation of std::basic_ostream it doesn't really matter: The compiler deduces the template arguments automatically. However, in cases where this function isn't mentioned together with something facilitating the template argument deduction, the compiler will fail to deduce the template arguments.

这篇关于std :: flush如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆