std::vector 如何访问它们之间有巨大差距的元素?

mil*_*bos 39 c++ algorithm templates iterator stdvector

有这个代码:

template <class IIt, class OIt>
OIt copy2(IIt begin, IIt end, OIt dest)
{
   while (begin != end)
   {
      //make gap between element addresses
      for (int i = 0; i < 99999999; i++)
      {
         dest++;
      }
      *dest++ = *begin++;
   }
   return dest;
}

int main(int argc, char** argv)
{
   vector<int> vec({ 1, 2, 3 });
   vector<int> vec2;
   copy2(vec.begin(), vec.end(), back_inserter(vec2));
   for (int i : vec2)
   {
      cout << i << endl;
   }
}
Run Code Online (Sandbox Code Playgroud)

编译需要很长时间,但最终会得到正确的输出

1
2
3
Run Code Online (Sandbox Code Playgroud)

问题是(在不知道 的内部实现的情况下std::vector,它是c-style数组?还是更复杂的结构?),当这些元素的地址(指针)不是连续的时,它如何正确地找到 中的那些元素?(即,由于迭代器/指针移动了)。for(int i:vec2)99999999

我认为需要OutputIterator拥有该属性,即只能对其进行一次访问,一次轮班。但是当你在访问它们之间多次移动(添加)它时,就会有一个差距,这对我来说是相当大的。那么它是如何编译的呢?

orl*_*rlp 63

你被愚弄了。

通过返回的迭代器std::back_inserterit++一个空操作。那么你正在创造的那些“差距”?是的,这一切都无济于事。

  • @Jeffrey我对他们前提的解释是,间隙在某处,并且在某处有一个指针,并且指针跳过间隙,而指针不应该这样做。 (11认同)
  • 但显然,OP 知道没有间隙,他们确实打印了向量......真的不清楚他们认为自己在用这个循环做什么。 (3认同)

JeJ*_*eJo 23

你的 for 循环

for (int i = 0; i < 99999999; i++)
{
    dest++;
}
Run Code Online (Sandbox Code Playgroud)

不做你想的。除了从0to迭代之外,它对那里没有影响99999999

当你查看时std::back_insert_iterator,它说

[...]。递增std::back_insert_iterator是空操作。

或者如23.5.2.1.1 中所述,它只是返回back_insert_iterator,而不对其进行任何操作。

constexpr back_insert_iterator& operator++();
constexpr back_insert_iterator  operator++(int);

#Returns: *this.
Run Code Online (Sandbox Code Playgroud)

意义dest++;没有影响。这使得您所做的整个假设完全无效。仅因为从0到的迭代,程序才需要很长时间才能执行99999999


它提出了一个问题:那为什么会出现std::back_insert_iterator<Container>::operator++过载呢?

从 cppreference std::back_insert_iterator<Container>::operator++

什么也没做。提供这些运算符重载是为了满足LegacyOutputIterator的要求 。它们使表达式*iter++=value*++iter=value用于将值输出(插入)到底层容器中成为可能。


eer*_*ika 22

std::vector,是c 风格的数组吗?

不完全是,但它创建的缓冲区在结构上是相同的。

当这些元素的地址(指针)不是连续的时?

前提是错误的。向量元素的内存地址是连续的。一个对象一个接一个地开始。

此外,它们是否是连续的并不重要。即使这些元素在内存中不连续,您也可以很好地迭代链表。

OutputIterator ...但是当您在访问它们之间多次移动(添加)它时,就会有一个差距

这个假设是不正确的。

在特殊情况下std::back_insert_iterator,文档说:

std::back_insert_iterator<Container>::operator++
Run Code Online (Sandbox Code Playgroud)

什么也没做。