std::unique_ptr 作为参数在 std::thread 中起作用 [重复]

Posted

技术标签:

【中文标题】std::unique_ptr 作为参数在 std::thread 中起作用 [重复]【英文标题】:std::unique_ptr as parameter to function in std::thread [duplicate] 【发布时间】:2015-11-23 11:50:26 【问题描述】:

因此,我尝试将 std::unique_ptr 作为参数传递给在单独线程中启动的函数,但在编译时出现了一个奇怪的错误:

1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional(1149): error C2280: 'std::unique_ptr<Widget,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function

此代码的简化版本,仍然重现相同的问题是:

#include <thread>
#include <memory>
#include <iostream>

class Widget

public:
  Widget() : m_data(0)
  
  

  void prepareData(int i)
  
    m_data = i;
  

  int getData() const
  
    return m_data;
  

private:
  int m_data;
;

void processWidget(std::unique_ptr<Widget> widget)

  std::cout << widget->getData() << std::endl;


int main()

  std::unique_ptr<Widget> widget(new Widget());
  widget->prepareData(42);

  std::thread t(processWidget, std::move(widget));
  t.join();

  return 0;

我的猜测是从main( 销毁Widget 对象有问题,但是我无法确定问题所在。是否有必要做一些额外的事情来清理那个变量?顺便说一句,我用的是VS2013。

【问题讨论】:

@DevSolar 不 std::thread 总是将 xvalue 传递给它的处理程序,这是 MSVC 故障吗? GCC 接受它。 std::thread t([&amp;widget]() processWidget(std::move(widget));); 也可以。 在 Orwel DevC++ 5.11 兄弟中运行良好!您的代码似乎没有任何问题 现在我有问题了!!为什么我无法通过reference 发送小部件!!!编译器显示错误!!! IIRC 这是 MSVC 中的一个已知问题。至少我记得在这里搜索过它,并且我的代码中的一个 cmets 是“使用 shared_ptr 和 bind,因为 VS 在 unique_ptr 上阻塞”并且似乎创建线程也可能通过 bind 进行 【参考方案1】:

您不能复制 unique_ptr,因此复制构造函数被禁用。那就是指向编译器错误。

您可以通过参考修复它:

void processWidget(std::unique_ptr<Widget>& widget)

【讨论】:

没有人在 OP 的代码中复制 @PiotrSkotnicki 不是直接,而是std::thread 的构造函数将其参数复制/移动到线程可访问存储,然后在调用函数本身时复制。 @sjdowling 您能否提供一个标准参考,说明std::thread 制作副本以调用其处理程序? 这不起作用,请检查我的 cmets 以及 move 语句是否正确并且在 Orwell DevC++ 中有效,问题出在 VS2013 而不是代码

以上是关于std::unique_ptr 作为参数在 std::thread 中起作用 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何创建一个可以将 std::unique_ptr 作为模板参数正常工作的容器?

本周小贴士#123: absl::optional和std::unique_ptr

使用已使用 new X() 创建的变量将 std::unique_ptr 传递给函数

`std::optional` 比 `std::shared_ptr` 和 `std::unique_ptr` 有啥优势?

为啥 std::unique_lock 改变 std::unique_ptr?

通过rvalue传递不会破坏对象