这是一个关于对象销毁与返回值优化的C++规范的问题。
我可以期望 RVO 在清理之前返回正确的值std::unique_ptr<>
吗?
Foo Bar()
{
std::unique_ptr<Foo> ptr = new Foo();
return *ptr;
}
它将返回带有或不带有 RVO 的正确值(在这种情况下没有 RVO)。该函数返回一个具体的Foo
,因此*ptr
将在销毁指针之前复制到返回值中。
这意味着,
Foo foo;
foo = Bar();
类似于(解开unique_ptr以更明确)
Foo foo;
Foo* ptr = new Foo;
foo = *ptr;
finally:
delete ptr;
当函数返回类类型对象时,仅在两种情况下允许使用 RVO:
- 返回的表达式是非易失性自动对象的名称,或
- 返回的表达式引用尚未绑定到引用的临时对象。
因此,您的代码不会触发 RVO。
如果使用自动存储声明Foo
对象,则允许编译器执行 RVO:
Foo bar()
{
Foo foo;
return foo; // foo can be constructed directly as the returned object
}
如果由于某种原因您必须使用 new
创建对象并希望消除复制操作,则可以使用 std::move
,这会将表达式更改为右值:
Foo bar()
{
std::unique_ptr<Foo> ptr(new Foo);
return std::move(*ptr); // No deep copy if Foo implements
// its own move constructor
}