Question
Initialization order of inherited constructors
I have this example:
#include <iostream>
#define print(X) std::cout << X << std::endl
struct B1 {
B1(int _i = 5): i(_i) { print("B1 constructor"); };
int i;
};
struct B2 {
B2(int _j = 7): j(_j) { print("B2 constructor"); }
int j;
};
struct D : B2, B1 {
using B1::B1;
};
int main(void)
{
D d = D{10};
print("B1::i = " << d.i);
print("B2::j = " << d.j);
}
The output of this program is:
B2 constructor
B1 constructor
B1::i = 10
B2::j = 7
Per §11.9.4[class.inhctor.init]/1:
When a constructor for type B is invoked to initialize an object of a different type D (that is, when the constructor was inherited ([namespace.udecl])), initialization proceeds as if a defaulted default constructor were used to initialize the D object and each base class subobject from which the constructor was inherited, except that the B subobject is initialized by the inherited constructor if the base class subobject were to be initialized as part of the D object ([class.base.init]). The invocation of the inherited constructor, including the evaluation of any arguments, is omitted if the B subobject is not to be initialized as part of the D object. The complete initialization is considered to be a single function call; in particular, unless omitted, the initialization of the inherited constructor's parameters is sequenced before the initialization of any part of the D object.
Firstly, per §11.9.4/1
, since D
inherits constructor B1(int)
from base B1
, that inherited constructor can initialize subobject B1
; further, the parameter _i
is fully initialized before initializing any part of D
, hence the inherited constructor D::B1(int)
is selected by overload resolution which initializes B1::i
members by mem-initializer-list.
Since B2 constructor
is printed first, this means that B2
constructor is called before B1
. So how member B2::j
is initialized with default argument 7
not value 10
that's passed in the call D{10}
?
I'm not sure whether that happened, but I can't understand the sequence of execution in this case. and where this behavior is necessary in the standard.