【问题标题】:Is the article Generic<Programming> Typed Buffers completely obsolete with C++ 11?文章 Generic<Programming> Typed Buffers 在 C++ 11 中完全过时了吗?
【发布时间】:2014-09-12 03:24:18
【问题描述】:

我正在阅读 Generic<Programming> Typed Buffers,来自 Andrei Alexandrescu 的一篇相当古老的文章。

我想知道它是否仍然有意义。 Alexandrescu 在他的文章中指出了std::vector 在性能至关重要时的一些问题:

  • 分配向量时不必要的数据初始化,我认为可以使用std::vector::reserve 解决
  • 用 C++11 和移动语义解决的昂贵的移动操作
  • 大多数编译器不会使用std::memcpy 和std::memmove 为char 等类型优化std::vector。现在对于主流编译器来说这是不正确的(据我所见)。
  • 指数增长。您不能通过简单的方法调用来缩小std::vector 的容量以适应大小。这也是不正确的,因为 C++11 和 std::vector::shrink_to_fit()

我的问题是,这篇文章是否完全过时了,我现在可以依靠向量(包括必要时的自定义分配器)来获得快速连续缓冲区吗?

【问题讨论】:

  • 最后一点不正确:shrink_to_fit 只能通过将数据复制到一个新的、更小的块中来进行收缩。
  • 第一点,你是说初始化还是分配?
  • 谢谢我会编辑这个问题,我的意思是shrink_to_fit是集成的,用户不能做不必要的副本,当然内部副本是制作的
  • 您不能使用 reserve 然后将数据传递给 C 函数(这就是本文所讨论的有关初始化的内容)。您必须调用resize,这确实会初始化数据。
  • @juanchopanza shrink_to_fit 可以使用分配器内部的知识来做一些事情,而不是将数据复制到新块。例如,如果分配器使用malloc/free 获取内存块shrink_to_fit 可以用realloc 实现,如果(a)is_trivially_move_constructible 类型或(b)realloc 实现已知当被要求缩小块时,永远不要在内存中重定位。

标签: c++ c++11 vector stl


【解决方案1】:

C++11 在很大程度上缩小了std::vector 和原始数组之间的差距(移动语义和shrink_to_fit 解决了Alexandrescu 的一些观点),但在某种程度上仍然存在利基; std::vector 继续对元素进行值初始化; reserve 无济于事,因为您无法访问保留的内存。您可以使用自定义分配器解决此问题,但这远不能令人满意。

另一方面,unique_ptr&lt;T[]&gt; 使在容器类中保存缓冲区更加简单,因为它在很大程度上解决了异常安全问题。 TS dynarray 在构造时提供固定大小的分配和默认初始化,看起来可能会缩小大部分剩余的差距。

Alexandrescu 的通用缓冲区占据的剩余位置是提供具有 O(n) 收缩和增长操作的默认初始化元素;这些通常作为容器类的组件没有用,如果需要,可以编写为非成员函数。

【讨论】:

  • 我不明白你为什么说不能访问保留的内存。我尝试使用reserve()然后data(),然后使用memcpy将此数据复制到分配的int*,它似乎工作。我想我错过了什么
  • @vac “它似乎有效”对于undefined behaviour 来说是一个无关紧要的观察。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 2017-03-13
  • 1970-01-01
  • 1970-01-01
  • 2015-11-21
  • 2014-03-31
  • 1970-01-01
相关资源
最近更新 更多