【问题标题】:Iterator category for circular buffer循环缓冲区的迭代器类别
【发布时间】:2020-06-23 22:11:37
【问题描述】:

我尝试实现以下类型的循环缓冲区。

为简单起见,我假设循环缓冲区只是具有RandomAccessIterator 的容器的容器适配器(如std::stack)。容器以某种方式调整大小/填充值,然后放置到适配器中。之后,底层容器的大小不应该改变。

显然c.begin() == c.end() 用于循环缓冲区。某些算法(例如,基于范围的 for 循环)对于循环缓冲区无法按预期工作(而不是 for (;;) 可以使用 assert(!c.empty()); auto beg = std::begin(c), it = beg; do { f(it); } while (++it != beg); 遍历循环缓冲区)。

当我尝试使用std::sort 对循环缓冲区进行排序时,出现了主要问题。从底层容器继承迭代器类别对于循环缓冲区迭代器是不公平的。循环缓冲区的迭代器应该几乎是RandomAccessIterator,但不是严格完全有序的(<><=>= 未定义)。 std::sort 的实现可以在内部使用operator <(并且确实如此)。

我无法定义自己的迭代器类别(例如,ModularIterator)并将其插入现有类别(例如std::is_base_of_v<std::bidirectional_iterator_tag, my_iterator_tag>std::is_base_of_v<my_iterator_tag, std::random_access_iterator_tag>)之间。算法也不是定制点。

我不想将iterator_category 设置为std::bidirectional_iterator_tag,因为std::equal_range 在对数时间内不起作用。

RandomAccessIterator 的严格总排序真的需要在算法中的某个地方还是可以避免?

有没有办法让<algorithm>s 为循环缓冲区工作?

是否在标准中疏忽了没有适合无序迭代器的迭代器类别,可以为O(1) 的任何步骤推进?

例如:https://wandbox.org/permlink/GH1JF4WK2IUUCRHg

【问题讨论】:

  • 听起来您希望标准库适应您的迭代器类型。似乎您假设您的迭代器类型基本上是原始指针的别名。您应该忘记这种先入之见,并编写一个与标准库函数兼容的迭代器。通过自己计算迭代器中的实际元素位置来使迭代器随机访问。确保 begin 不是 end
  • "显然 c.begin() == c.end() 用于循环缓冲区。"这一点都不明显。这是一个错误的实现。
  • @Barry 为什么不正确?标准中是否有禁止声明?
  • 因为这是迭代器抽象的工作方式。 c.begin() == c.end() 表示一个空范围。仅仅因为你的存储是循环的并不意味着范围是空的——抽象的重点是将算法与存储分开。由您来确保您的迭代器为您的存储做正确的事情(即++ii == j*ii + nj - i 等都是有意义的)。是的,您的迭代器应该是随机访问迭代器(因为这应该是一种廉价的操作)。
  • range-v3 用循环迭代器试验过一次; it was eventually abandoned "as a hopeless bug farm".

标签: c++ algorithm iterator language-lawyer c++20


【解决方案1】:

显然c.begin() == c.end() 用于循环缓冲区。某些算法(例如,基于范围的 for 循环)在循环缓冲区中无法按预期工作

更正:没有基于范围的算法(有意义地)适用于这样的范围,因为开始和结束迭代器相同的范围是空的。这是空范围的定义

你需要的是一个迭代器,它不仅知道它在缓冲区中的位置,还知道它在哪个循环上。开始迭代器可能位于位置索引 0,循环 0,而结束迭代器位于位置索引 0,循环 1。这两个迭代器将比较相等。当你增加一个迭代器越过循环边界时,它会将循环计数增加 1。相反,越过循环边界递减。

本质上,一个循环缓冲区迭代器应该代表一个无限可遍历的值范围。

关于总订单的部分有点像红鲱鱼。是的,随机访问迭代器需要一个总顺序,但是您希望 begin 和 end 相等而不是空范围这一事实是迭代器的基本设计问题。一旦你解决了这个问题,完全订购无限范围的能力自然会失效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-13
    • 2013-09-26
    • 1970-01-01
    • 2020-11-01
    相关资源
    最近更新 更多