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([&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` 有啥优势?