健全性检查:是否返回!来自 streambuf 派生类的溢出函数的 EOF 有意义吗?

Sanity check: Does returning !EOF from streambuf-derived class' overflow function make sense?

提问人:Niko O 提问时间:1/27/2023 更新时间:1/29/2023 访问量:87

问:

我发现关于被覆盖的 std::streambuf::overflow 函数应该如何简单地获取写入流的每个字符的有用信息,令人惊讶。所以我向 ChatGPT 寻求了一些指导。它不断回到这个概念:

int overflow(int c)
{
    if (c == EOF)
    {
        // Flush the buffer here
        return !EOF;
    }
    // Put c in the buffer here
    if (c == '\n')
    {
        // Flush the buffer here
    }
    return c;
}

当 c 是 时它返回,这真是太奇怪了。
这些文档没有详细说明“成功”的含义。
此页面表示,当调用 with 作为参数时(或发出“失败”信号时),它应该返回 (not)。
!EOFEOFEOF!EOFEOF

那么:我的怀疑是正确的,回到这里是错误的,我应该回来吗?
如果你能告诉我 ChatGPT 从哪里得到这个想法,Cookie 点。我在互联网上找不到其他任何地方。
!EOFEOFreturn !EOF;

C++ C++17 流buf

评论

0赞 Niko O 1/27/2023
@Someprogrammerdude 用EOF作为参数来称呼它被认为是“成功的”吗?此外,是一个常量值,所以我不确定你所说的“如果流已到达文件末尾,Treats::eof() 返回 true”是什么意思。 成为 ,变为 0。Traits::eof()!EOFfalse
0赞 Some programmer dude 1/27/2023
这可能与函数需要返回与成功不同的值有关。显然,该代码被认为是一个成功的案例。Traits::eof()EOF
0赞 Some programmer dude 1/27/2023
话虽如此,ChatGPT 对于实际和事实信息确实不可靠。它可以生成看起来不错、很真实的文本和代码,但仔细观察往往不是。ChatGPT 生成的答案在这里被禁止是有原因的。我不会相信它生成的任何代码。
0赞 n. m. could be an AI 1/27/2023
!EOF没有任何意义(这只是一种有趣的拼写常量的方式)。false
0赞 BoP 1/27/2023
还有一个功能。也许这就是让人工智能感到困惑的原因?当然与.Traits::not_eof()not_eof()!EOF

答:

1赞 Igor Tandetnik 1/29/2023 #1

这是 C++ 标准对返回值的评价:

[流buf.virt.put]

int_type overflow(int_type c = traits::eof());

6 返回:如果函数失败,则抛出异常。
否则,返回除指示成功之外的某个值。(304)
traits::eof()traits::eof()

(脚注304)通常,return 表示成功,但 returns 除外,在这种情况下,它将返回 。overflowctraits::eq_int_type(c, traits::eof())truetraits::not_eof(c)

因此,具体的返回值并不重要,重要的是它是否重要。您可能希望遵循一个(非规范性)约定。traits::eof()

回复:“成功”的含义:

[streambuf.virt.put]/5 要求:此虚函数的每个覆盖定义都应遵循以下约束:
...

  1. 假设是挂起序列中未消耗的字符数。如果为非零,则 和 应设置为: 以 开头的字符是关联的输出流。如果为零(已使用挂起序列的所有字符),则设置为 ,或者都设置为相同的非 null 值。rrpbase()pptr()pptr() - pbase() == rrpbase()rpbase()nullptrpbase()pptr()
  2. 如果将某些字符附加到关联的输出流失败,或者无法根据上述规则建立,则该函数可能会失败。pbase()pptr()

因此,如果函数无法实际写入底层介质,或者无法恢复不变量,则该函数将失败。如果它同时管理了这两个项目,它就会成功。

评论

0赞 Niko O 1/29/2023
因此,这只是那些愚蠢的 C++ 主义之一,将 int 用于本应是 bool 的东西。谢谢你的解释。
0赞 Igor Tandetnik 1/29/2023
我想@NikoO。Streams 库是很久以前由一个人设计的,并且远远早于标准化工作。我怀疑如果现在设计它,它看起来会大不相同。我的猜测是,在原始设计中,返回值不仅仅是一个布尔值;但那已经消失在时间的迷雾中。