(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();
答案 0 :(得分:3)
不,RVO不适用。 (N)RVO在标准中仅被定义为构造函数elision。
动机是,如果MyObj()
的构造函数抛出,则第二个代码片段myobj
已经存在,并且应该继续存在于调用{{{ 1}}。
除此之外,我认为一般不清楚如何实际建造就地。 getMyObj()
是一个已经构造的对象,只有myobj
“知道”如何用不同的资源替换它所拥有的任何资源。
但operator=
的返回值仍然可以直接构造,并且调用代码可以从getMyObj
(移动分配)中受益(如果有的话)。因此,代码必然需要复制构造或复制分配,但它确实需要一个无法省略的赋值。
如果所有内容都被内联,并且operator=(MyObj &&)
无法抛出,并且赋值没有副作用,那么在好日子,编译器可能会应用“as-if”规则,并优化而不管(N)RVO的具体规则!