If you are worried about the two new Bar
expressions interleaving and throwing before the handles are initialized to hold what they are meant, the standard doesn't allow it.
First in [intro.execution]
12 A full-expression is
- an init-declarator or a mem-initializer, including the constituent expressions of the initializer,
16 Every value computation and side effect associated with a
full-expression is sequenced before every value computation and side
effect associated with the next full-expression to be evaluated.
Without going too much into details, x{new Bar}
and y{new Bar}
in their entirety are both considered what standardese deems a "full-expression" (even though they are not expressions grammar-wise). The two paragraphs I quoted indicate that either the entire initialization of x
(which includes new Bar
) has to happen first, or the entire initialization of y
has to happen first. We know from [class.base.init]
13.3 - Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order
of the mem-initializers).
So x
is initialized in full, and then y
. So even if new Bar
throws while initializing y
, x
already owns the resource it's meant to hold. In which case, when the exception is thrown, the verbiage in [except.ctor] parageph 3 will apply to the fully constructed x
, and it will be destructed, thus releasing the resource.