<分区>
考虑这段代码:
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 创建的临时构造函数
反过来又被移动了,为什么这里会发生另一个看似额外的构造?