当将值复制到现有对象中时,(N)RVO 是否也会发生?
Does (N)RVO also happen when the value is being copied into an existent object?
(N)RVO 有助于避免在将 return 值分配给新变量时不必要地复制和创建临时对象(从而避免复制构造函数)。
所以像这样的东西应该由 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();
不,RVO 不适用。 (N)RVO 在标准中仅定义为构造函数省略。
的动机是,如果 MyObj()
的构造函数抛出,那么在第二个代码片段中 myobj
已经存在,并且应该继续存在于调用之前的状态getMyObj()
.
除此之外,我认为总体上不清楚如何实际实现就地施工。 myobj
是一个已经构造好的对象,只是operator=
"knows"如何替换它持有的任何资源,不同的资源。
getMyObj
的 return 值仍然可以直接构造,但是,调用代码可以从 operator=(MyObj &&)
(移动赋值)中获益(如果有的话)。因此,代码 不一定 需要复制构造或复制赋值,但它确实需要赋值,而赋值不能省略。
如果一切都是内联的,并且 MyObj()
不能抛出,并且赋值没有副作用,那么在好的日子里,编译器可能会应用 "as-if" 规则,并且无论如何都进行优化(N)RVO的具体规则!
(N)RVO 有助于避免在将 return 值分配给新变量时不必要地复制和创建临时对象(从而避免复制构造函数)。
所以像这样的东西应该由 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();
不,RVO 不适用。 (N)RVO 在标准中仅定义为构造函数省略。
的动机是,如果 MyObj()
的构造函数抛出,那么在第二个代码片段中 myobj
已经存在,并且应该继续存在于调用之前的状态getMyObj()
.
除此之外,我认为总体上不清楚如何实际实现就地施工。 myobj
是一个已经构造好的对象,只是operator=
"knows"如何替换它持有的任何资源,不同的资源。
getMyObj
的 return 值仍然可以直接构造,但是,调用代码可以从 operator=(MyObj &&)
(移动赋值)中获益(如果有的话)。因此,代码 不一定 需要复制构造或复制赋值,但它确实需要赋值,而赋值不能省略。
如果一切都是内联的,并且 MyObj()
不能抛出,并且赋值没有副作用,那么在好的日子里,编译器可能会应用 "as-if" 规则,并且无论如何都进行优化(N)RVO的具体规则!