提问人:Niko O 提问时间:1/27/2023 更新时间:1/29/2023 访问量:87
健全性检查:是否返回!来自 streambuf 派生类的溢出函数的 EOF 有意义吗?
Sanity check: Does returning !EOF from streambuf-derived class' overflow function make sense?
问:
我发现关于被覆盖的 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)。!EOF
EOF
EOF
!EOF
EOF
那么:我的怀疑是正确的,回到这里是错误的,我应该回来吗?
如果你能告诉我 ChatGPT 从哪里得到这个想法,Cookie 点。我在互联网上找不到其他任何地方。!EOF
EOF
return !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 除外,在这种情况下,它将返回 。
overflow
c
traits::eq_int_type(c, traits::eof())
true
traits::not_eof(c)
因此,具体的返回值并不重要,重要的是它是否重要。您可能希望遵循一个(非规范性)约定。traits::eof()
回复:“成功”的含义:
[streambuf.virt.put]/5 要求:此虚函数的每个覆盖定义都应遵循以下约束:
...
- 假设是挂起序列中未消耗的字符数。如果为非零,则 和 应设置为: 以 开头的字符是关联的输出流。如果为零(已使用挂起序列的所有字符),则设置为 ,或者都设置为相同的非 null 值。
r
r
pbase()
pptr()
pptr() - pbase() == r
r
pbase()
r
pbase()
nullptr
pbase()
pptr()
- 如果将某些字符附加到关联的输出流失败,或者无法根据上述规则建立,则该函数可能会失败。
pbase()
pptr()
因此,如果函数无法实际写入底层介质,或者无法恢复不变量,则该函数将失败。如果它同时管理了这两个项目,它就会成功。
评论
0赞
Niko O
1/29/2023
因此,这只是那些愚蠢的 C++ 主义之一,将 int 用于本应是 bool 的东西。谢谢你的解释。
0赞
Igor Tandetnik
1/29/2023
我想@NikoO。Streams 库是很久以前由一个人设计的,并且远远早于标准化工作。我怀疑如果现在设计它,它看起来会大不相同。我的猜测是,在原始设计中,返回值不仅仅是一个布尔值;但那已经消失在时间的迷雾中。
评论
Traits::eof()
!EOF
false
Traits::eof()
EOF
!EOF
没有任何意义(这只是一种有趣的拼写常量的方式)。false
Traits::not_eof()
not_eof()
!EOF