迭代器的后继者不一定是常规函数:它怎么可能?

alf*_*lfC 5 c++ iterator regular-type

编程元素的第91页中,Stepanov和McJones说Iterator的概念需要一个successor函数,但这不一定是常规的,因为

...... i = j并不意味着successor(i) = successor(j)......

(见在线页面)

我理解converse successor(i) = successor(j)并不暗示i=j(例如在两个空终止列表中)并且successor可能没有为某些输入定义该函数.但我不明白怎么可能i = j导致这种情况发生successor(i) != successor(j).

他们会指的是什么情况?也许某些迭代器会随机(如同)跳跃?或者某个迭代器具有隐藏状态,并且在指向同一个元素之后以不同于其他迭代器的方式"跳转"(并且在此意义上比较相等).

他们立即跳转到需要常规successor功能的改进(ForwardIterator),所以我不清楚.


最初我认为输入迭代器可以具有此属性.但是,我仍然很难看出这是否构成一个反例:(在STL的某个实施中).

#include <iostream>
#include <sstream>
#include <iterator>
#include <numeric>
#include <cassert>
using std::cout; using std::endl;
int main(){
    std::istream_iterator<int> it1(std::cin); // wait for one input
    std::istream_iterator<int> it2 = it1;
    assert(it1 == it2);
    cout << "*it1 = " << *it1 << endl;
    cout << "*it2 = " << *it2 << endl;
    cout << "now sucessor" << endl;
    ++it1; // wait for one input
    ++it2; // wait for another input
    assert(it1 == it2); // inputs still compare equal !
    cout << "*it1 = " << *it1 << endl;
    cout << "*it2 = " << *it2 << endl;
    assert(it1 == it2); // also here ! and yet they point to different values...
    assert(*it1 == *it2); // assert fails! 
}
Run Code Online (Sandbox Code Playgroud)

(用GCC 6.1编译)

sky*_*ack 3

一个例子可能是消耗数据流的后继函数(正如他们在书中提到的那样)。
当您读取第 i 个元素时,理论上您只能为其调用后继函数一次。如果您尝试调用它两次,结果会有所不同。
简单想象一下,successor(i)从流中读取下一个元素,即第i+1 个元素。它实际上意味着消耗它,并且它不再可用。如果再调用successor(i)一次,您将从流中获取第i+2 个元素。
因此,如果输入相同 ( i = j),则无法保证输出相同 ( successor(i) = successor(j))。