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

C++ 为什么在构造std::thread时参数移动了两次,c++,c++11,move,stdthread,C++,C++11,Move,Stdthread,考虑这个程序,它本质上创建了调用函数func(),并将arg作为参数的std::thread: #include <thread> #include <iostream> struct foo { foo() = default; foo(const foo&) { std::cout << "copy ctor" << std::endl; } foo(foo&&) noexcept { std::co

考虑这个程序,它本质上创建了调用函数
func()
,并将
arg
作为参数的
std::thread

#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();
}
据我所知,
arg
在线程对象中内部复制,然后作为右值(移动)传递给
func()
。因此,我期望一次复制构造一次移动构造


为什么会有第二步构造?

通过值将参数传递给
func
,该值应构成第二步。显然,
std::thread
在调用
func
之前会在内部存储它一次,就标准而言,AFAIK是绝对合法的

所以,我期望一次复制构造和一次移动构造

标准并没有这样说。允许实现执行额外的内部移动构造


但这样做可能会降低效率。这在即将发布的GCC 10版本中已经得到了修复。

比特相关:啊,事实上是一个复制品。遗憾的是,由于没有答案,它无法关闭(因为n.m.出于某种原因在评论部分写下了他们的答案)
copy ctor
move ctor
move ctor