我理解随机访问迭代器如何对std::vector
这样的连续容器起作用:迭代器只是维护一个指向当前元素的指针,并且任何加法/减法都应用于指针。
但是,我对于如何为非连续容器实现类似的功能感到困惑。我对std::deque:iterator
如何工作的第一个猜测是,它维护了一个指向它包含的连续内存组的表的指针,但我不确定。
典型的标准库如何实现这一目标?
答案 0 :(得分:4)
您可以粗略地满足std::deque
std::vector<std::unique_ptr<std::array<T,N>>>
的要求。加上一个低/高水印,告诉你第一个/最后一个元素在哪里。 (对于定义为N的实现,可能会随T
而变化,而std::array
实际上是正确对齐的未初始化内存的块,而不是std::array
,但您明白了这一点。
使用正常的指数增长,但在正面和背面都有。
查找只需(index+first)/N
和%N
即可找到块和子元素。
这比std::vector
查找更昂贵,但是是O(1)。
答案 1 :(得分:0)
可以通过存储指向引用值的指针和指向该值所在的连续内存块的双指针来实现deque迭代器。双指针指向由deque管理的块的连续指针数组。
class deque_iterator
{
T* value;
T** block;
…
}
因为value
和block
都指向连续的内存,所以你可以实现在恒定时间内查找迭代器之间距离的操作(例如从libc ++改编的例子)。
difference_type operator-(deque_iterator const& x, deque_iterator const& y)
{
return (x.block - y.block) * block_size
+ (x.value - *x.block)
- (y.value - *y.block);
}
请注意,虽然value
和push_front
等操作不会使push_back
失效,但block
可能会失效,这就是deque_iterator
无效的原因通过这样的行动。