为什么在构造 std::thread 时参数移动了两次

Sha*_*yan 6 c++ move c++11 stdthread

考虑这个方案,基本上创建std::thread调用该函数func()arg作为参数:

#include <thread>
#include <iostream>

struct foo {
   foo() = default;
   foo(const foo&) { std::cout << "copy ctor" << std::endl; }
   foo(foo&&) noexcept { std::cout << "move ctor" << std::endl; }
};

void func(foo){}

int main() {
   foo arg;
   std::thread th(func, arg);
   th.join();
}
Run Code Online (Sandbox Code Playgroud)

我的输出是

copy ctor
move ctor
move ctor
Run Code Online (Sandbox Code Playgroud)

据我了解arg是在线程对象内部复制,然后func()作为右值传递给(移动)。所以,我期望一个副本构造一个移动构造

为什么要进行二次施工?

bip*_*pll 3

您将参数传递给func值,这应该构成第二步。显然,std::thread在调用 之前,它会在内部再次存储一次func,据我所知,这在标准方面是绝对合法的。