代码之家  ›  专栏  ›  技术社区  ›  Evan Teran

增加已在流末尾的istream_迭代器的结果是什么?

  •  0
  • Evan Teran  · 技术社区  · 16 年前

    我看了一下标准,没有看到明显的答案。

    假设我这样做了:

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

    现在 is 位于流的末尾,等于 std::istream_iterator<char>() std::istream_迭代器<char>() ? 还是结果未定义?

    该标准明确规定: *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 回复  |  直到 16 年前
        1
  •  4
  •   Johannes Schaub - litb    16 年前

    C++03中关于输入迭代器需求的表72说明 ++r r 是可取消引用的。同样的先决条件也适用于 r++ .

    现在 24.5.1/1 谈到 istream_iterator

    结果 operator*

    综上所述 operator++ 在流结束时,未定义迭代器。

    ++r R 是可取消引用的。同样的先决条件也适用于 .

    现在 谈到 istream_迭代器

    结果 接线员* 未定义流的末尾。

    接线员++ 在流结束时,未定义迭代器。


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

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

    x.in_stream == y.in_stream
    

    哪里 in_stream 是一个指向流的指针,该流被迭代并公开到标准文本中,用于定义“仅公开”的行为和语义。现在,我能想到的唯一实现就是使用一个流结束迭代器,它将空指针存储为流指针。但是 接线员++ 定义为做具有以下效果的事情

    *in_stream >>value
    

    现在,如果您进入流结束状态,我们将设置 顺流而下 如果指向空指针,那么肯定会导致未定义的行为。

    因此,即使您单独使用istream迭代器,似乎也不能保证您的增量超过流结束值。

        2
  •  3
  •   Community Mohan Dere    6 年前

    未定义的行为

    使用错误的程序结构或错误的数据时可能出现的行为, 为了什么 本国际标准无任何要求。 当这 国际标准省略了对行为的任何明确定义的描述。