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

假设我已经这样做了:

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


现在is位于流的末尾,等于std::istream_iterator<char>()。如果再增加一次会怎样?它仍然等于std::istream_iterator<char>()吗?还是结果不确定?

该标准明确指出,如果*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?
}

最佳答案

C ++ 03中有关输入迭代器要求的表72表示++r的前提是r是可取消引用的。 r++具有相同的前提条件。

现在,24.5.1/1谈到istream_iterator


  未定义流末尾的operator*结果。


总之,operator++对流结束迭代器的影响是不确定的。

C ++ 03中有关输入迭代器要求的表72表示++r的前提是r是可取消引用的。 r++具有相同的前提条件。

现在,24.5.1/1谈到istream_iterator


  未定义流末尾的operator*结果。


总之,operator++对流结束迭代器的影响是不确定的。



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

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

x.in_stream == y.in_stream


其中,in_stream是指向迭代的流的指针-并公开到标准文本中,用于定义行为和语义(仅限于展示)。现在,我能想到的唯一实现此功能的方法是使用流结束迭代器,该迭代器将空指针存储为流指针。但是operator++被定义为具有以下作用的行为

*in_stream >>value


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

因此,即使您仅使用istream迭代器,也似乎无法保证可以增加到流结束值之后。

关于c++ - 增加已经在流末尾的istream_iterator的结果是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1307831/

10-11 23:05
查看更多