迭代器的继任者不一定是常规功能:如何可能

Successor of iterator is not necessarily a regular function: how is it possible?

本文关键字:功能 何可能 常规 继任者 不一定 迭代器      更新时间:2023-10-16

在《编程元素》第91页中,Stepanov和McJones说,迭代器的概念需要successor函数,但不一定是/em>常规,因为

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

(请参阅在线页面)

我理解相反的successor(i) = successor(j)并不意味着i=j(例如,在两个零终止列表中),并且可能无法为某些输入定义successor函数。但是我不明白i = j如何可能导致successor(i) != successor(j)

他们会指的是什么情况?也许是某些迭代器会随机(如在leatory)啤酒花中吗?或某些具有隐藏状态和"跳跃"的迭代器与指向相同元素后的其他迭代器不同(从这个意义上进行比较)。

他们立即跳到需要常规successor功能的改进(前向材料),因此我不清楚。


最初,我认为输入迭代器可以具有此属性。但是,我仍然很难看这是否构成反例:(在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! 
}

(用GCC 6.1编译)

考虑定义为:

的类型iter
struct iter { unsigned value; };
inline bool operator==(iter const& x, iter const& y) {
  return x.value == y.value;
}
inline bool operator!=(iter const& x, iter const& y) {
  return !(x == y);
}
auto source(iter const& x) {
  return x.value;
}
iter successor(iter const&) {
  std::random_device engine{};
  std::uniform_int_distribution<unsigned> dist{};
  return {dist(engine)};
}

iirc,iter满足EOP Iterator概念的要求:它是Regularsource是常规功能,successor尤其是 not> not> not 常规。给定两个类型iter的对象ij,因此i == j很可能successor(i) != successor(j)

一个示例可以是连续函数,它消耗了数据流(如他们在书中提到的那样)。
读取 i-th 元素后,理论上只能为其调用连续功能函数一次。如果您尝试调用两次,结果是不同的。
只需想象successor(i)从流中读取下一个元素,即 i-th 1 元素。它实际上意味着消耗它,并且不再可用。如果您再次致电successor(i),您将从流中获取 i-th 2 元素。
因此,如果输入相同(i = j),则无法保证输出相同(successor(i) = successor(j))。