0

我希望有人可以阐明 RVO 在 g++ 中的作用。我有一些需要修改的第三方软件,我想尽可能地对其进行优化,但我无法弄清楚 RVO 究竟做了什么,以及它何时启动。我目前的结构看起来像:

class Foo {
private:
    Bar     myBar;
public:
    Bar &getBar() { return myBar; };
};

调用者通常这样使用它:

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()速度会很慢,因为它必须转换Bar2rt(不可避免),然后将'rt'复制到调用者的本地上下文中(可以避免???)......我不是清楚 RVO 是否可以防止复制,如果可以,幕后到底发生了什么。

4

1 回答 1

2

我不清楚 RVO 是否可以防止复制

是的,这就是它的目的。

此外,从 C++17 开始需要防止复制。(对不起,不是;那是为了返回prvalue;不过,您实际上可以依赖NRVO)

如果副本的成本足够高,可以一开始就关心这些,那么它可能也应该是可移动的,在这种情况下,我们再次不关心成本。

如果是这样,引擎盖下到底发生了什么。

没关系。

但是,在您的 2017 PC 上,粗略地说,rt将在调用者的堆栈框架中“创建”,而不是在此处本地创建。因此,根本不需要副本。

(而且,确实,不要返回对局部变量的引用。)

于 2017-07-13T14:34:46.720 回答