0

我查看了标准,但没有看到明显的答案。

假设我已经这样做了:

std::istream_iterator<char> is(file);
while(is != std::istream_iterator<char>()) {
    ++is;
}

现在is位于流的末尾并且等于std::istream_iterator<char>(). 如果我再增加一次会发生什么?还是等于std::istream_iterator<char>()?或 os 结果未定义?

该标准明确指出,如果位于流的末尾,*is则为未定义的行为。is但我还没有看到任何关于迭代超出流末端的东西......

编辑

我问是因为我偶然发现了一些类似这样的代码:

// skip 2 input chars
++is;
++is;
if(is != std::istream_iterator<char>()) {
    // continue using is and do some work...but what if the first
    // increment made it EOS? is this check valid?
}
4

2 回答 2

4

++rC++03 中关于输入迭代器要求的表 72表明is的前提条件r是可取消引用的。相同的前提条件适用于r++

现在,24.5.1/1istream_iterator

operator*未定义 on an end of stream的结果。

总之,operator++对流尾迭代器的影响是未定义的。

++rC++03 中关于输入迭代器要求的表 72表明is的前提条件r是可取消引用的。相同的前提条件适用于r++

现在,24.5.1/1istream_iterator

operator*未定义 on an end of stream的结果。

总之,operator++对流尾迭代器的影响是未定义的。


请注意,我认为只有当您编写或使用采用表现出该行为的输入迭代器的算法,然后传递 istream 迭代器时,此结论才会使行为未定义。从仅显式使用istream 迭代器本身,而不将其视为输入迭代器并依赖其不变量,我认为上面的结论不太正确(例如,我们可能有一个不需要r可取消引用的类)。

但是看看 istream 迭代器是如何描述的,operator++在到达流值末尾之后的调用也会导致未定义的行为。operator==因为它被定义为等价于

x.in_stream == y.in_stream

Wherein_stream是指向迭代的流的指针 - 并暴露在标准文本中,用于定义行为和语义“仅展示”。现在,我能想到的唯一实现是使用流结束迭代器,该迭代器将空指针存储为流指针。但是operator++被定义为做一些具有以下效果的事情

*in_stream >>value

现在,如果您进入流结束状态,并且我们将设置in_stream为空指针,那么肯定会产生未定义的行为。

因此,即使您单独使用 istream 迭代器,似乎也无法保证您可以递增超过流结束值。

于 2009-08-20T22:37:24.263 回答
3

如果未定义,则未定义 :-) 在标准(C++0X 的最新草案)中,重点是我的:

未定义的行为

行为,例如在使用错误程序结构或错误数据时可能出现的行为,本国际标准对此没有要求。当本国际标准省略对任何明确的行为定义的描述时,也可能会出现未定义的行为。

于 2009-08-20T18:01:41.387 回答