【问题标题】:Passing class object into thread将类对象传递给线程
【发布时间】:2018-01-15 18:12:10
【问题描述】:
void thread_func(Color& r)
{
   //
}

void f()
{
   Color r(red_state);
   thread t(thread_func, r);
   t.join();
}

简化。我在网上找不到任何与这种特定情况相匹配的东西(传递给非成员线程函数的类对象)。我尝试了一些建议(添加 '&'、std::ref(r)、使用向量等),但我不断收到以下错误:

error: no type named 'type' in 'class std::result_of<void (*(Color*))(Color&)>'
error: use of deleted function 'Color::Color(const Color&)'

后者让我认为它与复制构造函数有关,但我认为通过引用传递它不应该影响它?任何提示或反馈将不胜感激。

【问题讨论】:

  • 以下评论中引用的 AMA 示例有效。您可以添加您的功能以找出它在哪里中断。显然,您的附加代码(此处未显示)使用复制构造,该构造已在 Color 类中删除。如果我们没有看到整个代码,我们不能告诉你为什么。与第一个错误相同。
  • 你可以让线程的例程成为一个通过引用捕获对象的 lambda。

标签: c++ multithreading


【解决方案1】:

使用std::ref 传递引用。即:

thread t(thread_func, std::ref(r));

了解std::reference_wrapper 以了解原因:http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper

【讨论】:

  • @JMoore 这是最小的工作example
  • 啊,有趣。我想那个错误一定是在我班上的某个地方……这至少结束了这个问题。谢谢。
  • @JMoore 很可能您的Color 类缺少复制构造函数。
  • @AMA 是的,但如果使用std::ref,则在 OP 的代码中不需要复制 ctor。它可能需要在未显示的代码内部某处。也许,在thread_func 正文中,或者...
【解决方案2】:

当您尝试将对象作为参数传递给函数时,您是在尝试按值传递它。 对复杂对象而不只是原语这样做会导致 C++ 调用复制构造函数以构造一个新对象,该对象是您传递的对象的副本。

这样做会产生同样的结果,正如您所看到的,它试图调用 Color::Color(const Color&amp;),如前所述,它已被删除。

您可以尝试传递 Color*(指向 Color 的指针),这应该可以工作,但这意味着您将使用完全相同的对象,如果您不小心从两个不同的对象中使用它,这可能会很危险线程。 您对第一个线程上的对象所做的每项更改也将适用于第二个线程。

【讨论】:

  • 感谢您的警告。我会试一试。
  • 这段代码应该模拟那里发生的事情wandbox.org/permlink/MArdSkuw2KBvhAUP注意复制构造函数被删除了。
  • 我不同意。 threads 构造函数通过转发引用传递参数。在内部,它们被复制(这是需要复制 ctor 的地方),并且副本通过引用传递给 thread_func。在这种情况下没有应用传值机制。
  • 引用只存在于编译时,一旦它需要将项目传递到不同的位置(不能在编译时),它必须创建自己的对象副本(传递值本身) .那是我按按值
  • 没关系。您关于调用 copy ctor 的推理是错误的。传值机制需要复制(或移动)ctor,传引用(这里就是这种情况)不需要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多