我可以将其用于什么目的? 为什么它比random_access_iterator好? 如果使用它,有什么好处吗?
答案 0 :(得分:4)
对于连续迭代器,您可以获取指向迭代器“指向”元素的指针,并将其用作指向连续数组的指针。
使用随机访问迭代器无法保证。
请记住,例如df1[,NumberOfChangesPast3Days := c(1,2,2,2,1,1,1,2,2,2),]
LET day num hasChanged NumberOfChangesPast3Days
1: a 1 5 TRUE 1
2: a 2 6 TRUE 2
3: a 3 6 FALSE 2
4: a 4 7 TRUE 2
5: a 5 7 FALSE 1
6: b 1 1 TRUE 1
7: b 2 1 FALSE 1
8: b 3 3 TRUE 2
9: b 4 1 TRUE 2
10: b 5 1 FALSE 2
是随机访问的容器,但通常不是连续的容器(与std::deque
既是随机访问的又是连续的容器相反)。
答案 1 :(得分:4)
在C ++ 17中,没有std::contiguous_iterator
之类的东西。但是有ContiguousIterator named requirement。这表示元素序列上的随机访问迭代器,其中每个元素以与数组完全相同的方式连续存储。这意味着,在给定迭代器指向value_type
的指针的情况下,可以对该指针执行指针算术,该指针算术的工作方式与对相应迭代器执行相同算术的方式完全相同。
这样做的目的是允许在连续的迭代器上更有效地实现算法。或者禁止算法在不连续的迭代器上使用。一个重要的例子是,如果您试图将C ++迭代器传递到基于数组指针的C接口中。您可以将此类接口包装在通用算法后面,以验证模板中迭代器的连续性。
或者至少在理论上您可以;在C ++ 17中,这实际上是不可能的。原因是实际上没有一种方法可以测试迭代器是否为ContiguousIterator。无法询问指针是否对从迭代器指向元素的指针进行指针算术合法。而且没有std::contiguous_iterator_category
可以用于此类迭代器(因为这可能会导致兼容性问题)。因此,您无法使用SFINAE工具来验证迭代器是连续的。
C ++ 20的std::contiguous_iterator
concept解决了此问题。它还可以解决连续迭代器的另一个问题。请参阅上面对ContiguousIterator行为的说明,从我们有一个指向范围中元素的指针开始。好吧,你是怎么得到的?显而易见的方法是执行类似std::addressof(*it)
的操作,但是如果it
是最终迭代器怎么办?最终迭代器不可取消引用,因此您不能这样做。基本上,即使您知道迭代器是连续的,也要如何将其转换为等效的指针?
std::contiguous_iterator
概念解决了这两个问题。 std::to_address
可用,它将把任何连续的迭代器转换成它的等效指针值。而且,迭代器必须提供一个traits标记,以表明它实际上是一个连续的迭代器,以防默认的to_address
实现对一个不连续的迭代器有效。
答案 2 :(得分:3)
随机访问迭代器仅需要一个恒定的时间(iterator) + (offset)
,而连续迭代器则更能保证std::addressof(*((iterator) + (offset))) == std::addressof(*(iterator)) + (offset)
(不考虑过载的operator&
)。
这基本上意味着迭代器是指针或指针周围的光包装,因此它等效于指向其元素的指针,而随机访问迭代器可以做更多的事情,但代价是可能体积更大且无法把它变成一个简单的指针。
答案 3 :(得分:0)
作为C ++ 20概念,如果容器是连续的,我希望您可以使用它来指定其他算法。也许是利用缓存局部性。