From cppreference,
When copy elision occurs, the implementation treats the source and target of the omitted copy/move (since C++11) operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the optimization (except that, if the parameter of the selected constructor is an rvalue reference to object type, the destruction occurs when the target would have been destroyed) (since C++17).
For a simple case like A a = returnA();
, I can understand that the object is not destroyed in returnA()
and instead the destruction occurs as in the case A a;
which is the later time.
I can't think of a case which the opposite happens such that the source of the copy/move operation is destroyed first. Also I would like an example of the added statement since C++17 (exception when parameter of selected constructor is an rvalue reference to object type)
The symmetric case where the source outlives the target is when the prvalue is a parameter:
Because the result of
returnA()
is a temporary, its lifetime extends to the end of thereturn
statement’s full-expression. The implementation may identify it withf
’s parameter, but may not destroy it whenf
returns, so the dereference inreturnInt
is valid. (Note that parameters may survive that long anyway.)The adjustment in C++17 (along with such elision being guaranteed) is that if you (would) move the prvalue, it may be destroyed when the parameter is (since you shouldn’t be relying on its contents anyway). If that’s when
f
returns, the (ill-advised) code above becomes invalid ifA
is made movable.