【问题标题】:Is there a use case for std::unique_ptr<std::array<T,N>>是否有 std::unique_ptr<std::array<T,N>> 的用例
【发布时间】:2017-10-01 08:01:36
【问题描述】:

我遇到了类似的东西:

using arr_t=std::array<std::array<std::array<int,1000>,1000>,1000>;
std::unique_ptr<arr_t> u_ptr;

显然,使用唯一指针是为了克服 stackoverflow 问题。是否有任何情况下使用以前的代码而不仅仅是使用 std::vectorstd::unique_ptr&lt;std::array&lt;T,N&gt;&gt; 有真正的用例吗?

【问题讨论】:

  • 您可以确定arr_t 永远不会调整大小。优化可能会发现这很有用。
  • std::vector 不能保证分配所需的确切空间量 - 它可能会分配更多空间。 std::array 具有固定大小。
  • arr_t 将分配连续的内存块,std::vector&lt;std::vectorstd::vector&lt;&gt;&gt;&gt; 将在 1000 * sizeof(int) 每个块中分配内存。这可能很重要。

标签: c++ arrays c++11 smart-pointers


【解决方案1】:

上面的代码生成一个包含十亿个元素的连续缓冲区,通过[] 访问,您可以将元素作为一个 3 维 1000 面立方体。

一个由多个向量组成的向量将是一堆由指针和所有权语义链接的不连续缓冲区。

我怀疑你在暗示

using u_ptr=std::vector<std::array<std::array<int,1000>,1000>>;

然后在创建后将 arr_t 的大小调整为 1000。这在句柄对象中具有额外的 2 个指针开销的适度成本。它还允许可变大小,这意味着确保它是预期的固定大小是用户代码必须确保的。您可能希望阻止一堆方法,基本上是 unique_ptr 不公开的所有方法,以确保安全,或审核您的代码不使用其中任何方法。

其中一些操作可能非常昂贵; .push_back({}) 将重新分配一个千兆字节。

现在,也许你打算永远不要这样称呼它;但是,如果您有处理向量的通用代码,则必须审核它的 all 以确保它们都不执行这些操作。不可能有一个 vector 的非常量句柄,它不能调整它的大小,例如,此时没有滚动你自己的跨度类。

我们可以使用私有继承和using 语句来阻止我们不想公开的方法,但此时我们最终要做大部分工作以回到unique_ptr 解决方案。

【讨论】:

  • 好吧,你可以拥有一个包含私有std::vector的瘦类,并转发所有相关方法——你甚至可以根据大小对其进行模板化,比如@ 987654331@。如果你做得好,审计它也不会太难。从std::array继承当然是个坏主意,同意。
  • @TobySpeight 不,我的意思是从std::vector 私下继承,然后是using vector&lt;T&gt;::operator[]using vector&lt;T&gt;::size 要重新导出的接口。当您只是尝试重新导出另一个类的接口的某些部分时,私有继承涉及的样板文件(以及拼写错误的机会)要少得多。
  • 我没有考虑私有继承,但这是有道理的。我被“阻止”方法的谈论误导了,而不是选择发布哪些方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-21
  • 2019-11-07
  • 1970-01-01
  • 2015-07-23
  • 2018-02-02
相关资源
最近更新 更多