我读了很多答案,局部变量可以通过
std::move
安全地返回。
但是当我尝试时,编译器显示如下警告。
class MyClass {};
MyClass&& func() {
MyClass c;
return std::move(c);
}
int main() {
func();
}
warning: reference to stack memory associated with local variable 'c' returned [-Wreturn-stack-address]
return std::move(c);
^
上面的代码有什么问题?
在您的代码示例中,您返回对局部变量的(右值)引用。由于函数调用完成后局部变量就被销毁了,使用这样的返回值是未定义的行为。
另一方面,如果您按值返回(您应该这么做),那么使用
std::move
可能不是一个好主意。
事实上,由于 NRVO(命名返回值优化),编译器可以执行复制省略以避免不必要的复制/移动。
实际上,NRVO 不是强制性的,因此移动构造函数可能会被调用(但实际上,这不会发生,因为大多数编译器都会执行优化)。 知道,如果你明确使用
std::move
,由于移动构造函数可能有副作用,你使你的变量不符合NRVO的条件,这就将上面的
“移动构造函数可能被称为”翻译成“移动构造函数将会被称为“,这是一种悲观主义。 因此,除非您确实想调用移动构造函数(例如,对于内部实现的特定行为),否则您不应该返回
std::move
。
如果这只是性能问题,编译器会通过复制省略做得比你更好。
MyClass func() // Return by value
{
MyClass c;
/*
Do whatever you want with c.
*/
return c; // NRVO (copy elision)
}