Background
Mandatory elision of copy/move operations may be already familiar to many C++ programmers. Examples copied from the linked text. Copies and moves must not be inserted by the compiler:
- In the initialization of an object, when the initializer expression is a prvalue of the same class type (ignoring cv-qualification) as the variable type:
T x = T(T(f())); // only one call to default constructor of T, to initialize x
This can only apply when the object being initialized is known not to be a potentially-overlapping subobject:
struct C { /* ... */ }; C f(); struct D; D g(); struct D : C { D() : C(f()) {} // no elision when initializing a base-class subobject D(int) : D(g()) {} // no elision because the D object being initialized might // be a base-class subobject of some other class };
This is implemented in practice by giving f
a hidden extra argument telling it where to construct its return value.
Question
Why are potentially-overlapping subobjects not subject to mandatory elision? There's no reason f
couldn't construct its return value directly in the base class section of D
.