【问题标题】:Can C++ streambuf methods throw exceptions?C++ streambuf 方法可以抛出异常吗?
【发布时间】:2013-09-30 23:39:57
【问题描述】:

我正在尝试找到一种方法来获取读取或写入到可靠流中的字符数,即使出现错误并且读取/写入结束很短。

我正在做这样的事情:

return stream.rdbuf()->sputn(buffer, buffer_size);

但是如果overflow 的streambuf 实现被允许抛出异常,这将不起作用。是吗?我无法在任何地方找到它的记录。

【问题讨论】:

    标签: c++ exception iostream


    【解决方案1】:

    basic_streambuf::overflow 允许在失败时抛出异常,如 27.6.3.4.5/6 中所述,遗憾的是无法确保 编译时该函数永远不会抛出异常。

    似乎你的运气已经不多了,唯一 100% 确定 overflow 不会引发异常的方法是编写你自己的 streambuf,它在失败时不会这样做。


    [27.6.3.4.5/2-3] int_type overflow(int_type = c = traits::eof ())
    ...

    [27.6.3.4.5/5]

    要求:此虚函数的每个覆盖定义都应遵守以下约束:

    1) 消费一个字符对相关输出的影响 序列被指定309

    2) 令 r 为待处理序列中的字符数 not 消耗。如果 r 不为零,则应设置 pbase() 和 pptr() 那:pptr() - pbase() == r 和从 pbase() 开始的 r 字符是相关的输出流。如果 r 为零(待处理的所有字符 序列已被消耗)然后将 pbase() 设置为 NULL,或者 pbase() 和 pptr() 都设置为相同的 NULL 非值。

    3) 如果将某些字符附加到 关联的输出流失败或无法建立 pbase() 和 pptr() 按照上面的规则。

    [27.6.3.4.5/6]

    返回traits::eof ()如果函数失败则抛出异常

    【讨论】:

    • 不幸的是,我正在编写一个适配器来将 streambufs 转换为另一个接口 (Microsoft COM IStream)。我不控制或实现流缓冲区。
    • 当然必须有办法做到这一点。否则,如果目标流出错,源流如何知道目标流消耗了多少字符?
    • @thehouse 流操作可能会失败,但您仍然可以调用适当的函数来获取有关流的信息。例如,您可以在可能失败的调用之前和之后比较 gptr 的值.. 或类似的,它应该在理论上起作用。
    • 如果sputn/sgetn 中途调用overflow`underflow` 是否可靠。如果缓冲区被写出(或根本没有缓冲区)pptr/gptr 可以定位回缓冲区的开头或设置为NULL,这将阻止这样的计算。还是我误会了?
    • 另外,您对标准的引用似乎暗示pptr() 如果流操作失败则不可靠
    猜你喜欢
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 2017-01-04
    • 2012-07-03
    • 2015-02-13
    • 1970-01-01
    相关资源
    最近更新 更多