我希望有人可以了解一下RVO在g ++中的作用。我有一些我需要修改的第三方软件,我想尽可能地优化它,但是我无法弄清楚RVO究竟做了什么,以及什么时候开始。我目前的结构看起来像:
int x = foo.getBar().getX();
呼叫者通常使用它:
Foo
因为返回是一个引用,所以没有所需结构的副本,这很好地表现了性能。
我需要修改Bar2
以使用Bar
代替getBar()
作为其内部结构,但是,我需要保持convertBar2ToBar(const struct Bar2 &bar2, struct Bar &bar)
接口可用于第三方呼叫者。我有一个函数Bar& Foo::getBar() { Bar rt; convertBar2ToBar(myBar2, rt); return rt }
,可以有效地在两种结构类型之间进行转换,但是我很担心,就像我一样:
rt
然后返回对堆栈上变量的引用,可以对其进行潦草地写入。我也可以修改程序以返回Bar Foo::getBar() { Bar rt; convertBar2ToBar(myBar2, rt); return rt }
的副本,如下所示:
Foo.getBar().getX()
但现在我担心我的Bar2
会变慢,因为它必须将rt
转换为{{1}}(不可避免),然后复制'rt'到a调用者的本地上下文(可避免???)......我不清楚RVO是否可以阻止复制,如果是这样的话,究竟发生了什么事情。
答案 0 :(得分:2)
我不清楚RVO是否可以阻止复制
是的,这是它的目的。
此外,必需以防止C ++ 17版本的复制。
(对不起,不是;那是为了返回一个prvalue;仍然,你现在可以依赖NRVO)
如果副本的价格足够昂贵,首先要关心这些,那么它可能也应该是可移动的,在这种情况下我们再也不关心成本。
如果是的话,究竟是怎么回事。
没关系。
但是,在2017年的PC上,粗略地说,rt
将在调用者的堆栈框架中“创建”而不是在本地。因此,根本不需要复制。
(实际上,不要返回对局部变量的引用。)