【问题标题】:C++ - How am I able to call a copy constructor for std::thread?C++ - 我如何能够调用 std::thread 的复制构造函数?
【发布时间】:2021-01-07 21:06:00
【问题描述】:

所以根据https://en.cppreference.com/w/cpp/thread/thread/threadstd::thread 的复制构造函数被删除,这是我不能做的原因(导致编译错误):

std::thread t1;
std::thread t2 = t1;

但是我能做到:

std::thread t1;
t1 = std::thread();

我的印象是上面的代码创建了一个临时的std::thread对象并将其复制到t1,但复制构造函数不存在(如顶部的sn-p所示,它不会编译) .

那么第二个sn-p到底发生了什么?

【问题讨论】:

  • 你熟悉移动语义吗?如果没有,请参阅What is move semantics?
  • 由于t1 = std::thread(); 中等号的左侧是现有变量,而不是声明,您应该考虑assignment 而不是construction(从某种意义上说,这并不重要,因为复制分配也被删除了。因此这是一个评论,而不是一个答案。)

标签: c++ c++17


【解决方案1】:

第二个使用移动赋值。 std::thread 可以移动,但不能复制。

这也应该有效:std::thread t2 = std::move(t1);,这将使 t2 管理 t1 正在管理的任何线程,而 t1 将为空。

【讨论】:

  • 如果 std::thread did 有一个复制构造函数,那么它会被复制吗?即,如果没有复制构造函数,是否尝试复制和使用 move 的行为?还是这样做总是调用移动?
  • @user3690467:不; move 是一个优化的副本。如果移动不会导致问题,则使用移动,例如在纯右值或直接请求的情况下(即:std::move)。
  • 如果需要,请阅读以下内容以了解上述一些术语:What are rvalues, lvalues, xvalues, glvalues, and prvalues?
  • 右值的赋值或构造首先尝试移动,只有在移动构造函数/赋值操作不存在时才回退到复制。 (请注意,“普通”类默认具有编译器生成的移动操作,因此在这些情况下不会有回退——对此的全面讨论超出了 cmets 的范围:)
猜你喜欢
  • 1970-01-01
  • 2023-03-31
  • 2014-01-29
  • 2022-01-22
  • 2011-04-27
  • 1970-01-01
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多