递增已经在流末尾的istream_iterator的结果是什么?

时间:2009-08-20 17:55:45

标签: c++ istream istream-iterator

我看过标准,并没有看到明显的答案。

假设我已经这样做了:

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?
}

2 个答案:

答案 0 :(得分:4)

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

现在,24.5.1/1istream_iterator

  

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

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

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

现在,24.5.1/1istream_iterator

  

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

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


请注意,我认为只有当您编写或使用一个算法来获取表现该行为的输入迭代器,然后传递一个istream迭代器时,这个结论才会使行为不确定。仅从使用 istream迭代器本身显式,而不将其视为输入迭代器并依赖其不变量,那么我认为上面的结论并不完全正确(我们可能有一个类没有要求r可解除引用,例如)。

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

x.in_stream == y.in_stream

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

*in_stream >>value

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

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

答案 1 :(得分:3)

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

  

未定义的行为

     

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