Consider:
#include
#include
class Foo
{
public:
Foo( char const * msg ) : x( y )
{
y =
You can do so1 because:
x
and y
are both in scope already ([basic.scope.class]/1).y
is obtained already ([basic.life]/7), that reference can be bound to y
.Using that reference inside the constructor's compound statement (after member initialization is all over) is also fine. That is because y
is considered initialized, and x
refers now to an object whose lifetime has started.
1 - There's a caveat for language lawyers. Technically, a reference needs to be bound to a valid object ([dcl.ref]/5), meaning one whose lifetime has started. However, like Core Language issue 363 details, it's expected to work! The problematic wording and a possible resolution is discussed in Core Language issue 453 (courtesy of @T.C. in a deleted comment). There's a bug in the standard, but your code is intended to be well formed, and implementations are generally aware of it.
But what about member variables not in the initializer list?
Whether the variables are in the initializer list or not, is irrelevant in this regard. If a variable is not in initializer list (nor has a default member initializer), then it is default initialized.
y
is initialized after x
. This is not because of the member initializer list, because the member initializer list does not affect the order of initialization of members. Members are initialized in the order of their declaration.
However, whether y
is initialized or not is also irrelevant. It is well formed to bind a reference to to a member before the member is initialized (except binding to a virtual base of uninitialized member; that would have UB).
In regard to safety (or perhaps correctness more accurately), I recommend that you take some time to consider what happens when Foo
is copied. What will x
refer to? Is that what the user of the class would expect?
Can I safely create references to them as showcased?
Yes, you can. The storage address of the member y
is known regardless initialized it or not, so x(y)
reference initialization is legal.