我能用它做什么?为什么它比random_access_iterator好?如果我用它有什么好处吗?
发布于 2020-03-08 15:17:11
在C++17中,没有std::contiguous_iterator这样的东西。然而,有ContiguousIterator命名需求。这表示元素序列上的随机访问迭代器,其中每个元素以与数组完全相同的方式连续存储。这意味着,给定来自迭代器的指向value_type的指针,可以对该指针执行指针算法,该指针的工作方式与在相应的迭代器上执行相同的算法完全相同。
这样做的目的是允许在连续迭代器上更有效地实现算法。或者禁止在不连续的迭代器上使用算法。如果您试图将C++迭代器传递到基于指向数组的指针的C接口中,这就说明了这一点。您可以将这些接口封装在泛型算法后面,以验证模板中迭代器的连续性。
或者至少,你可以在理论上;在C++17中,这是不可能的。原因是实际上没有一种方法来测试迭代器是否是ContiguousIterator。如果对迭代器中指向元素的指针执行指针算法是合法的,则无法询问指针。而且没有任何std::contiguous_iterator_category可以用于这样的迭代器(因为这可能导致兼容性问题)。所以您不能使用SFINAE工具来验证迭代器是连续的。
C++20的概念解决了这个问题。它还解决了使用连续迭代器的另一个问题。参见,上面对ContiguousIterator行为的解释始于我们有一个指向范围内的元素的指针。那你是怎么弄到的?显而易见的方法是做一些类似std::addressof(*it)的事情,但是如果it是最终迭代器呢?终端迭代器是不能取消引用的,所以您不能这样做。基本上,即使您知道迭代器是连续的,如何将其转换为等效的指针?
std::contiguous_iterator概念解决了这两个问题。std::to_address是可用的,它将将任何连续迭代器转换为它的等效指针值。迭代器必须提供一个特性标记来表示它实际上是一个连续迭代器,以防默认的to_address实现碰巧对非连续迭代器有效。
发布于 2020-03-08 13:28:14
对于连续迭代器,您可以获得一个指向迭代器“指向”的元素的指针,并将其用作指向连续数组的指针。
这不能用随机访问迭代器来保证。
请记住,例如,std::deque是一个随机访问容器,但它通常不是一个连续容器(与std::vector相反,后者既是随机访问,也是连续访问)。
发布于 2020-03-08 13:26:27
随机访问迭代器只需要一个恒定时间的(iterator) + (offset),而连续迭代器更能保证std::addressof(*((iterator) + (offset))) == std::addressof(*(iterator)) + (offset) (不考虑重载的operator&s)。
这基本上意味着迭代器是指针或指针周围的光包装器,因此它相当于指向其元素的指针,而随机访问迭代器可以完成更多的任务,代价是它可能体积更大,无法将其转化为简单的指针。
https://stackoverflow.com/questions/60587869
复制相似问题