我对下面代码的成功编译感到非常困惑。函数'g'中的变量't'显然是左值。当'g'返回到main函数时,'t'应该被复制。但是,线程对象是不可复制的,那么为什么它能成功编译呢?
#include <thread>void some_other_function(int) { return;}std::thread g(){ std::thread t(some_other_function,42); return t;}int main() { g(); return 0;}
#include <thread>
void some_other_function(int) {
return;
}
std::thread g()
{
std::thread t(some_other_function,42);
return t;
int main() {
g();
return 0;
9ceoxa921#
当你return一个局部变量时,将使用移动构造函数而不是复制构造函数(如果可用)。虽然std::thread没有复制构造函数,但它有一个移动构造函数,所以这将起作用。请参见Automatic_move_from_local_variables_and_parameters由于NRVO(命名返回值优化),编译器也可能完全省略移动,但这并不能保证。
return
std::thread
wbrvyc0a2#
代码编译是因为Named Return Value Optimization (NRVO),或者说是因为无法执行时发生的隐式移动。无论发生哪种情况,都不会使用复制构造函数。这种技术可以在任何时候通过名称返回局部变量,例如:
在你的例子中。可以将本地对象t视为函数外部的返回对象,因此不会调用移动或复制构造函数。如上所述,如果编译器不能执行NRVO,则移动构造函数是一个回退。std::thread是不可复制的,但是可以移动,所以这段代码可以工作。
t
std::mutex
2条答案
按热度按时间9ceoxa921#
当你
return
一个局部变量时,将使用移动构造函数而不是复制构造函数(如果可用)。虽然std::thread
没有复制构造函数,但它有一个移动构造函数,所以这将起作用。请参见Automatic_move_from_local_variables_and_parameters
由于NRVO(命名返回值优化),编译器也可能完全省略移动,但这并不能保证。
wbrvyc0a2#
代码编译是因为Named Return Value Optimization (NRVO),或者说是因为无法执行时发生的隐式移动。无论发生哪种情况,都不会使用复制构造函数。
这种技术可以在任何时候通过名称返回局部变量,例如:
在你的例子中。可以将本地对象
t
视为函数外部的返回对象,因此不会调用移动或复制构造函数。如上所述,如果编译器不能执行NRVO,则移动构造函数是一个回退。std::thread
是不可复制的,但是可以移动,所以这段代码可以工作。std::mutex
,您的代码将无法编译。*