【问题标题】:std::vector<T*> vs std::vector<T> for 64-bit T64 位 T 的 std::vector<T*> 与 std::vector<T>
【发布时间】:2017-09-01 06:13:56
【问题描述】:

在 3D 几何引擎代码中,我读到:

std::vector&lt;GA_Offset*&gt; 似乎是错误的,GA_Offset 只是一个 64 位的 integerstd::vector&lt;GA_Offset&gt; 会更好。

其中GA_Offset aka long int 可能是几何结构中元素的非连续偏移。 GA_Offsets 即使在它之前的元素被删除时也保持不变,但如果在它之前插入一个元素,或者如果元素列表被碎片整理,则会失效。

在我短暂的 C++ 经验中,我了解到引用和指针比传递值更好。现在我有点困惑了。

为什么在std::vector 中存储值比指针更好? 64 位 int 有何不同?

【问题讨论】:

  • “在我短暂的 C++ 经验中,我了解到引用和指针比传递值更好。” - 恐怕你学错了。
  • @RichardHodges:传递引用通常比传递值好。
  • @BoundaryImposition 自 std::move 和复制省略出现以来,按值传递通常比按引用传递更好(更有效)。当然,如果被调用者要获得数据的所有权。
  • @RichardHodges:关键在于后半部分。我的大部分功能都没有所有权。我敢打赌,大多数其他人的功能也是如此。无论哪种方式,我们都不能就该主题做出广泛的声明,因为(像往常一样)这取决于!
  • 看起来你将不得不忘记一两件事。

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


【解决方案1】:

传递和存储是两个不同的东西。

确实,在传递参数时,通常需要引用。

然而,存储指针和引用是你不会做的事情,除非你真的需要。它使事情变得非常复杂,需要仔细的对象生命周期管理。如果您不需要它,您只需存储值并让移动语义处理其余部分(向量尤其如此,因为它们拥有其元素的所有权)。

在这种情况下std::vector&lt;GA_Offset*&gt; 是否优于std::vector&lt;GA_Offset&gt; 完全取决于应用程序。可能是容器出于某种操作原因故意存储“句柄”。我们无法判断,因为这取决于向量应该做什么。

【讨论】:

    【解决方案2】:

    如果T 是64 位整数,std::vector&lt;T&gt; 确实有意义,因为它的内存布局只是Ts 的缓存友好连续数组:

    +---------+ 
    |T|T|...|T|
    +---------+
    

    另一方面,std::vector&lt;T*&gt; 是一种更复杂的数据结构,您可以在其中连续存储指针;但是指向的项目(整数)在内存中是not 连续的:

    +--------------+ 
    |T* | T*|...|T*|
    +--------------+
     |   |       |
     \-> \->     \->
    

    因此,对于一个简单的整数Tvector&lt;T*&gt;vector&lt;T&gt;效率低且对缓存更不友好。

    我肯定会建议使用 vector&lt;T&gt; 来表示 64 位整数 T为什么您需要T* 的额外间接级别?

    此外,在 STL 容器中存储 raw 指针时要注意。原始的 observing 指针很好;但是原始拥有指针是“泄漏”的来源,您应该考虑存储智能拥有指针(例如std::vector&lt;std::unique_ptr&lt;T&gt;&gt;)。但是,同样,这对于简单的 64 位整数类型没有多大意义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-02
      • 2019-10-20
      • 2016-03-31
      • 2012-06-21
      • 2019-11-07
      • 2021-06-02
      • 1970-01-01
      相关资源
      最近更新 更多