是否可以编写符合标准的随机访问(或至少前向)整数迭代器

Is it possible to write standard conforming random access (or at least forward) Integer Iterator?

本文关键字:迭代器 整数 访问 随机 标准 是否      更新时间:2023-10-16

假设我们有一个函数f,它取整数并返回一个单调增加的值。我们想要找到极小的CCD_ 2使得CCD_。为了简单起见,假设答案在[l;r)范围内。显然,我们可以编写自己的二进制搜索实现,但我们希望使用现有的实现(std::patition_point)。

如此天真的实现将(可能)奏效:

// f;
std::vector<int> v(r - l);
std::iota(v.begin(), v.end(), l);
answer = l + partition_point(v.begin(), v.end(), [&](int x) {
    return f(x) <= C;
}) - v.begin();

显而易见的问题是,我们必须存储所有的数字,这需要大量的内存,也需要时间来填充阵列

下一个逻辑思想是以这种方式将整数包装到迭代器:

struct IntIterator: std::iterator<std::random_access_iterator_tag, int> {
    int current;
    IntIterator(int i) : current(i) {}
    int operator*() const { return current; }
    IntIterator& operator++() { ++current; return *this; }
    IntIterator& operator+=(size_t n) { current += (int)n; return *this; }
    IntIterator operator+(size_t n) const { return current+(int)n;  }
    size_t operator-(IntIterator that) const { return size_t(current - that.current); }
    // others operators to conform 
};
answer = partition_point(IntIterator{l}, IntIterator{r}, [&](int x) {
    return f(x) <= C;
});

这将适用于我的编译器(标准库),但不符合随机访问迭代器,因为

  • 运算符*应返回std::iterator_traits<IntIterator>::reference
  • 如果我们将std::iterator_traits<IntIterator>::reference更改为int(例如,将模板参数更改为std::iterator),它将无法满足前向迭代器的要求

    如果X是可变迭代器,则reference是对T的引用;如果X是常量迭代器,reference是常量T的引用,

  • 如果我们将operator*的返回类型更改为[const ]T&,它将无法满足前向迭代器的另一个要求

    如果a和b都是可解引用的,则a == b当且仅当*a*b绑定到同一对象。

所以我不明白如何使它符合要求,并质疑它是否可能。

迭代器共享一个指向缓存映射的指针。

缓存映射将index映射到(count,value),其中count是该索引处的迭代器数。

迭代器会记住它是否调用了*

调用*时,如果缺少该值,则会填充该值。不管怎样,计数都会递增,然后返回对值的引用。

当迭代器被破坏或迭代器移动(++)时,如果调用了*,则计数会递减。

如果计数减为零,则删除该条目。

这将缓存同一索引的所有有效迭代器在其集体重叠生存期内的值。

如果x0是可变迭代器,则reference是对T的引用;如果X是常量迭代器,则reference是对const T 的引用

我认为你不应该把这个要求看得太重。标准库包含一个容器(std::vector<bool>),其const_iteratoriterator不能满足此要求。我知道有一种观点认为"std::vector<bool>不是容器",但我更倾向于认为引用的要求限制性太强,而不是完全同意这种观点。