c++ - 为什么这个构造函数在传递给 std::thread 时被调用 3 次?

标签 c++ multithreading

<分区>

考虑这段代码:

class Widget {
public:
   Widget() { coutDefaultCtor();  }
   Widget(const Widget& w) { coutCopyCtor(); }
   Widget(Widget&& w) {  coutMoveCtor(); }

  ~Widget() = default; 

  void coutDefaultCtor() {
      std::cout << " called default Widget ctor " << std::endl;
  }

  void coutMoveCtor() {
      std::cout << " called move Widget ctor " << std::endl;
  }

  void coutCopyCtor() {
      std::cout << " called copy Widget ctor " << std::endl;
  }

  void doSomething() const { }
};

void takeWidget(const Widget& ref) {
  ref.doSomething();
}

int main() {
   Widget widget;

   std::thread t(takeWidget, widget);
   t.join();
   // expect 2 ctor calls
   // but calls 3
}   

据我所知,std::thread 将始终按值复制参数。 如果在某种情况下,入口点函数被定义为采用右值或 const 左值引用(此处相同),则将在内部创建该类型的临时值并作为右值传递。

上述代码的输出打印了 3 次 "called Widget ctor "。 每个构造函数、默认值、复制和移动一个。

我只期待 2 次,一次是在 main() 中调用的 widget 默认构造函数和 std::thread 创建的临时构造函数 反过来又被移动了,为什么这里会发生另一个看似额外的构造?

最佳答案

它是 C++ 标准库的一个实现细节,在不同的实现中可能有所不同。 std::thread t(takeWidget, widget) 中发生的事情比简单地调用 takeWidget(widget) 还要多。例如,在 GCC 实现中,thread 构造函数调用 make_tuple(),它会根据参数的类型移动或复制参数。

关于c++ - 为什么这个构造函数在传递给 std::thread 时被调用 3 次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57246412/

相关文章:

Java 强制停止线程在循环周期内执行

c++ - 无法将 'v8::MaybeLocal<v8::String>' 转换为 'v8::Local<v8::Value>'

c++ - 为什么这个 SOR 求解器的速度取决于输入?

c++ - 带有参数 C++ 的 void 函数指针 vector

c# - 锁定在整个应用程序中使用的对象的线程实例是一种好习惯吗?

ios - Swift,应用程序在模拟器的后台运行,但不在设备上运行

c++ - Mutex 没有按预期工作

c# - 暂停/恢复 For 循环?

c++ - 如何搜索确切的单词?

c++ - 我想打印单词的缩写,但不知道我做错了什么