【问题标题】:Does std::endl << std::flush have a purpose?std::endl << std::flush 有目的吗?
【发布时间】:2018-11-15 08:22:44
【问题描述】:

std::flush 在我正在查看的所有遗留代码中使用 std::endl 之后。当我第一次看到这个时,我的想法是看std::endlstd::flush的描述是多余的:

http://en.cppreference.com/w/cpp/io/manip/endl

http://en.cppreference.com/w/cpp/io/manip/flush

这是我在旧版源代码中看到的示例:

std::cout << "Generic Notification" << std::endl << std::flush;

但是,多年来,许多高级软件开发人员都看到了这段代码,我想知道我是否遗漏了一些细节。在std::endl 之后添加std::flush 有什么目的吗?

【问题讨论】:

  • 如果不是 std::cout 但其他一些流可能是有原因的......
  • @user463035818 那会是什么? std::endl 定义为“结束行和刷新”。
  • @Angew 我只是考虑了 OP 将原始代码中的任何流替换为 std::cout 以实现 mcve 的可能性。当然,即使对于自定义流式对象,flush 在那个地方也不应该有任何用处
  • 我的第一条评论更准确:flush 如果不是标准流,可能是有原因的,尽管它仍然不是一个好的理由,因为流不会在 @987654335 上刷新@可以认为是坏了
  • 也许从来没有人有过这样的机会告诉老年人这是没有意义的;)

标签: c++ flush endl


【解决方案1】:

没有任何目的。

如果我必须推测为什么您的遗留代码包含这些行,有几种可能性,从(我认为是)最可能的情况开始:

  • 有人错误地将显式调用添加到std::flush,高级开发人员认为这不是需要修复的问题
  • 代码起源于 C++ 标准被广泛采用之前的一段时间,在那个时候,本地编译器对 std::endl 的实现没有触发刷新,这意味着您的高级开发人员(正确地)理解它是必要的
  • 旧版本的 C++ 标准可能不需要std::endl 来触发刷新
  • 您的高级开发人员对std::endl 的行为有误。
  • 您的执行环境是一个奇怪的庞然大物,实际上需要刷新输出两次才能获得预期的结果。

【讨论】:

  • 对源代码进行文本搜索&替换时也会出现类似这样的傻事,比如:replace &lt;&lt; '\n'with &lt;&lt; std::endl
  • 很好的答案,但是“C++ 标准的旧版本……”——不,C++98 是第一个标准,它确实需要flush。充其量,标准库的某些早期版本可能表现不同,尽管我对此表示怀疑。顺便说一句,我可以想到一个原因,尽管他们没有意识到它会刷新,但他们会使用 endl 而不是 '\n’,这是一个没有 LF 行终止符的系统(很可能是 Windows)。当然,这在cout/cerr 和文本模式ofstream 上都不是必需的,然后endl 甚至对二进制ofstream 都没有帮助,但这可能是错误的推理。
  • 我特别喜欢最后一个场景。
【解决方案2】:

我将添加到其他有效答案中,通常情况下,std::flushstd::endl 都没有一个好的目的。

基本上,std::endl = 开始新行 + 刷新流。但是,很多人倾向于以std::endl 结束他们的台词,因为它“听起来不错”——结束台词。但我们实际上很少需要刷新输出流。有时我们会这样做(例如,当我们期待用户对字符串的回复,或者以最小的延迟监控我们的输出很重要时) - 但这是例外,而不是规则。

所以,这可能需要一点时间来适应,但我们真的应该默认为简单:

std::cout << bunch_of_stuff << '\n';

就是这样!

【讨论】:

  • 是的!如果您需要将输出刷新到终端,请使用 std::cerr
【解决方案3】:

在符合标准的环境中,std::flush 在此代码中没有任何用处。

写这篇文章的人要么不完全理解 std::endl 的语义,要么正在解决他们的编译器或执行环境的一些限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 2017-05-13
    • 2020-03-19
    • 2015-09-17
    • 1970-01-01
    相关资源
    最近更新 更多