价值回报是否意味着额外的拷贝和额外的开销?C++

Does return-by-value mean extra copies and extra overhead? C++

本文关键字:开销 C++ 拷贝 意味着 回报 是否      更新时间:2023-10-16

考虑以下内容:

class Foo { ... };
Foo rbv();
void caller()
{
  Foo x = rbv(); ← the return-value of rbv() goes into x
  ...
}
Foo rbv()
{
  ...
  return Foo(42, 73); ← suppose Foo has a ctor Foo::Foo(int a, int b)
}

将构造多少个Foo类型的对象?

也许吧。

在C++11中,如果值有move构造函数,则通过移动而不是复制来返回值。这可能比复制效率高得多。

在某些情况下,例如返回局部变量或临时变量时(如您在此处所做的),移动或复制可以被删除。该值直接创建到调用方的堆栈帧中,因此在返回时不需要移动或复制它。喜欢缩写词的人有时会称之为(N)RVO-(命名)回报值优化。

同样,也可以消除从临时返回值到x的复制或移动。

任何合适的编译器都会实现这种优化,因此您的代码应该只创建一个Foo。您可以通过使析构函数打印一条消息来验证这一点,并注意到它只执行一次:http://ideone.com/xydJqY.如果禁用优化,则最多可能有三个对象。

最多可以有两个副本:一个从临时Foo(42, 73)到函数的返回值,另一个从函数的返回到x。但是,这两个副本都有资格进行副本省略,这允许不进行复制,而是直接在目标中构建对象,相当于Foo x(42, 73);

您可能能够控制编译器利用副本省略的程度;例如,在GCC中,您可以使用-fno-elide-constructors来获取所有两个副本。