[英]How are random access iterators for non-contiguous containers (such as std::deque) implemented?
I understand how random access iterators work for contiguous containers like std::vector
: the iterator simply maintains a pointer to the current element and any additions/subtractions are applied to the pointer. 我理解随机访问迭代器如何对连续容器(如std::vector
起作用:迭代器只是维护一个指向当前元素的指针,并且任何加法/减法都应用于指针。
However, I'm baffled as to how similar functionality could be implemented for a non-contiguous container. 但是,我对于如何为非连续容器实现类似的功能感到困惑。 My first guess for how std::deque:iterator
works, is that it maintains a pointer to some table of the groups of contiguous memory it contains, but I'm not sure. 我对std::deque:iterator
如何工作的第一个猜测是,它维护了一个指向它包含的连续内存组的表的指针,但我不确定。
How would a typical standard library implement this? 典型的标准库如何实现这一点?
You can satisfy the requirememts of a std::deque
with a std::vector<std::unique_ptr<std::array<T,N>>>
roughly. 你可以用std::vector<std::unique_ptr<std::array<T,N>>>
粗略地满足std::deque
的requirememts。 plus a low/high water mark telling you where the first/last elements are. 加上一个低/高水印,告诉你第一个/最后一个元素在哪里。 (for an implementation defined N that could vary with T
, and the std::array
s are actually blocks of properly aligned uninitialized memory and not std::array
s, but you get the idea). (对于一个实现定义的N可能随T
而变化,而std::array
实际上是正确对齐的未初始化内存的块而不是std::array
s,但你明白了)。
Use usual exponential growth, but on both front and back. 使用通常的指数增长,但在正面和背面。
Lookup simply does (index+first)/N
and %N
to find the block and sub element. Lookup只是(index+first)/N
和%N
来查找块和子元素。
This is more expensive than a std::vector
lookup, but is O(1). 这比std::vector
查找更昂贵,但是是O(1)。
A deque iterator can be implemented by storing both a pointer to the referenced value and a double pointer to the contiguous block of memory in which that value is located. deque迭代器可以通过存储指向引用值的指针和指向该值所在的连续内存块的双指针来实现。 The double pointer points into a contiguous array of pointers to blocks managed by the deque. 双指针指向由deque管理的块的连续指针数组。
class deque_iterator
{
T* value;
T** block;
…
}
Because both value
and block
point into contiguous memory, you can implement operations such finding the distance between iterators in constant time (example adapted from libc++). 因为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);
}
Note that, while value
will not be invalidated by operations such as push_front
and push_back
, block
might be, which is why deque_iterator
is invalidated by such operations. 请注意,虽然push_front
和push_back
等操作不会使value
无效,但可能是block
,这就是deque_iterator
被此类操作无效的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.