0

(N)RVO 有助于在将返回值分配给新变量时避免不必要的复制和创建临时对象(从而避免复制构造函数)。

所以像这样的事情应该由 RVO 优化:

MyObj getMyObj() {
  return MyObj();
}

MyObj myobj = getMyObj();

但是,调用站点对象已经存在时也会发生这种情况吗?(即在使用=运算符而不是复制构造函数的情况下)。我试图找到有关此的文献,但 (N)RVO 似乎总是被描述为避免使用复制构造函数。不确定在这种情况下修改调用站点对象是否真的安全。

MyObj myobj;

//will getMyObj() first create a temporary object and then copy it via the = operator?
myobj = getMyObj();
4

1 回答 1

3

不,RVO 不适用。(N)RVO 在标准中仅定义为构造函数省略。

其动机是,如果MyObj()throws 的构造函数,那么在第二个代码片段myobj中已经存在,并且应该继续以它在调用之前的状态存在getMyObj()

除此之外,我认为一般情况下如何实际实现就地施工还不清楚。myobj是一个已经构建的对象,并且只operator=“知道”如何用不同的资源替换它拥有的任何资源。

但是,返回值getMyObj仍然可以直接构造,并且调用代码可以从operator=(MyObj &&)(移动赋值)中受益(如果有的话)。所以代码不一定需要复制构造或复制分配,但它确实需要分配,这是不能省略的。

如果一切都是内联的,并且MyObj()不能抛出,并且赋值没有副作用,那么在好的一天,编译器可能会应用“as-if”规则,并且不管 (N)RVO 的具体规则如何进行优化!

于 2015-10-25T22:13:02.040 回答