[class.inhctor.init] (original) (raw)

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.

[Example 1: struct B1 { B1(int, ...) { } };struct B2 { B2(double) { } };int get();struct D1 : B1 { using B1::B1; int x;int y = get();};void test() { D1 d(2, 3, 4); D1 e; } struct D2 : B2 { using B2::B2; B1 b;}; D2 f(1.0); struct W { W(int); };struct X : virtual W { using W::W; X() = delete; };struct Y : X { using X::X; };struct Z : Y, virtual W { using Y::Y; }; Z z(0); template<class T> struct Log : T { using T::T; ~Log() { std::clog << "Destroying wrapper" << std::endl; } };

Class template Log wraps any class and forwards all of its constructors, while writing a message to the standard log whenever an object of class Log is destroyed.

— _end example_]

[Example 2: struct V { V() = default; V(int); };struct Q { Q(); };struct A : virtual V, Q { using V::V; A() = delete;};int bar() { return 42; } struct B : A { B() : A(bar()) {} };struct C : B {};void foo() { C c; } — _end example_]