【问题标题】:best c++11 way to store a vector of pointers存储指针向量的最佳 C++11 方法
【发布时间】:2015-03-13 16:59:07
【问题描述】:

我想存储一个std::threads的向量

目前,我将其实现为std::vector<std::thread*> 但是,这需要手动删除std::threads

最优雅的 c++11 方法是什么?我可以看到std::shared_ptr,但这不是矫枉过正吗?指针是唯一的,但是std::vector需要临时复制一下。

也许我不需要指针,但std::thread 是不可复制的,我想我需要。

谢谢!

【问题讨论】:

  • 不,std::vector 支持仅移动类型。如果您确实需要指针向量,可以查看boost::ptr_vector
  • "但是,这需要手动删除 std::threads" 为什么每个人都认为必须删除每个指针?
  • @juanchopanza 因为每个分配有 new 的对象都需要被删除——显式地或通过 RAII(智能指针)。
  • @DaleWilson 每个指针都必须指向一个现在用 new 分配的对象?
  • 如果您不打算复制std::thread*,可以直接使用std::unique_ptr,您只需要确保使用移动方式获取std::vector 的值。跨度>

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


【解决方案1】:

从 C++11 开始,vector 只要求它的值是可移动的,就像 thread 一样。所以vector<thread> 应该可以满足你的需求。

对于不可复制类型的操作有一些限制 - 您不能将值复制入或出,只能移动或放置它们 - 但这些很容易适应。

如果您确实需要存储不可移动的类型(例如mutex),那么unique_ptr 可能是最好的选择;或者像 dequelist 这样不需要移动其值的容器。

【讨论】:

    【解决方案2】:

    你可以使用std::vector<std::thread>emplace_back

    threads.emplace_back([](int i){ ++i; }, 10);
    

    emplace_back 使用完美转发将其参数直接传递给std::thread 构造函数,并将新对象放入vector 内部内存中,类似于:

    new (vector_ptr + offset) std::thread(args...);
    

    它只涉及移动 - 一种处理对象的新语义,它可以替代复制,并且在资源使用方面可能更便宜。 std::thread 支持移动

    【讨论】:

    • @rici:线程是可移动的,足以调整向量的大小。
    • @rici,如果你知道最大线程数,你可以直接调用reserve()
    • @myaut:如果类型真的是不可移动的,那也无济于事;编译器仍然需要生成代码来调整大小,即使它永远不会被调用。但问题是关于可移动类型,因此无论是否需要调整大小,使用矢量都可以。
    • @MikeSeymour:当然,我认为这个问题是关于 vector<thread> 的(正如 OP 帖子的第一句话所说)。但是,我检查了 gcc - 似乎 emplace_back() 需要移动,并且不适用于不可移动的类型。
    • @myaut:emplace_back 需要移动(编译),因为它可能会调用调整大小,并且向量不知道您已经保留了尽可能多的空间。根据 Mike 之前的评论。
    【解决方案3】:

    如果您的编译器支持 c++11,请使用 std::unique_ptr,如果您的编译器不支持,请使用 boost::shared_ptr。

    不,这不是矫枉过正——这是很好的编程。

    【讨论】:

    • 为什么不是std::thread 本身?它和unique_ptr 一样可移动。添加不必要的间接是大材小用,也不是好的编程。 (而且如果编译器不支持C++11,也不支持线程)
    • 好点。我关注的是指针问题,而不是线程问题(请参阅问题的标题)如果对象是可移动的(哪些线程是),那么您的答案会更好。
    • 为什么以及如何在非 C++11 编译器上使用 std::shared_ptr
    • @JohnDibling std::vector<std::shared_ptr<whatever> > 工作得很好。 std::shared_ptrs 是可移动和可复制的,即使 whatever 不是。
    • @DaleWilson:让我不要那么模棱两可:std::shared_ptr 已添加到 C++11。如果没有 C++11 编译器,就不能使用std::shared_ptr'
    猜你喜欢
    • 2015-08-07
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    • 2020-12-30
    • 2010-09-12
    • 2020-07-23
    相关资源
    最近更新 更多