为什么不存在std :: vector :: push_front()?

sou*_*uki 5 c++ vector

既然std::vector::push_back()存在,为什么不std::vector::push_front()存在呢?

我知道还有其他存储对象的工作方式几乎相同,并且具有两者push_back()push_front()函数的实现,但我很好奇为什么std::vector没有.

72D*_*BE9 9

你不想在矢量上推送push_front.向前面添加元素意味着将向量中的每个元素移回一个元素:O(n)复制.表现糟糕.

  • @Tyker为什么?如果最后有空间你不需要更多存储空间,你只需要移动/复制所有存储空间.这应该只需要一个额外的构造来构造最后一个元素. (5认同)
  • @Tyker:不."push_front"必须移动现有的对象,但它可以通过向后循环将它们移动到位. (3认同)
  • @tyker如果大小为5且容量为10,则将元素推到前面不会导致重新分配。唯一会发生的情况是当大小等于容量时,这与 push_back 没有什么不同 (2认同)
  • @NathanOliver,已经很长一段时间了,但是为了他人的利益而回应您的评论 - 请不要将其视为个人:您真的不想向前移动所有元素,即使您不必重新分配。移动本身的成本非常高 - 正如该响应者提到的 O(N)。如果你移动了,它会以一种邪恶的方式使现有的迭代器失效。 (2认同)

Pli*_*der 9

有一个重要原因:std::vector<> 是一个连续的单端数组容器。它分配内存并在分配区域的开头开始写入元素。它通常分配比存储所有当前元素所需的更多内存,因此当您调用 push_back() 时,它会在末尾写入新元素并增加其元素计数。它快速高效。

另一方面,Push_front() 需要在所有当前元素之前以某种方式在位置 [0] 处写入新元素 - 但这并非微不足道,因为您的数组位置 [0] 已经被占用。Push_front() 会导致整个数组被重新复制,以便可以修改它的前端。如果没有设计 std::vector<> 类,这将是一种低效的操作。

当然,您仍然可以通过调用

std::vector::insert(begin(), 1, val)
Run Code Online (Sandbox Code Playgroud)

但它会导致整个数组被复制只是为了添加一个元素。

  • 不,移动是指与这里发生的事情无关的不同场景。您不能通过“移动”其余元素来将第一个元素添加到连续数组中;复制将以一种或另一种方式参与。 (4认同)
  • 那么,为什么存在 `vector::insert()` 函数呢? (4认同)
  • 在现代 C++ 中,移动 `std::vector` 中的元素通常是通过移动它们而不是复制它们来完成的(如果 move 是 `noexcept`)。 (2认同)
  • @Fayeure,因为即使他们想阻止它,他们也不能否认它的需要。就我个人而言,我并不关心避免语法糖只是因为语言设计者得出结论这是一个不好的运行操作......如果他们如此关心它,他们可以改为有编译器警告。事实上,人们会浪费时间找出困难的方法来做到这一点,将代码留在其中,而忘记了这是非常低效的。 (2认同)