struct complex {
complex();
complex(double);
complex(double,double);
};
complex sqrt(complex,complex);
complex a(1); // initialize by a call of complex(double)
complex b = a; // initialize by a copy of a
complex c = complex(1,2); // construct complex(1,2) using complex(double,double),
// copy/move it into c
complex d = sqrt(b,c); // call sqrt(complex,complex) and copy/move the result into d
complex e; // initialize by a call of complex()
complex f = 3; // construct complex(3) using complex(double), copy/move it into f
complex g = { 1, 2 }; // initialize by a call of complex(double, double)
— end example
complex v[6] = { 1, complex(1,2), complex(), 2 };
struct X {
int i;
float f;
complex c;
} x = { 99, 88.8, 77.7 };ctor-initializer: : mem-initializer-list
mem-initializer-list: mem-initializer ... mem-initializer-list , mem-initializer ...
mem-initializer: mem-initializer-id ( expression-list ) mem-initializer-id braced-init-list
mem-initializer-id: class-or-decltype identifier
struct A { A(); };
typedef A global_A;
struct B { };
struct C: public A, public B { C(); };
C::C(): global_A() { } // mem-initializer for base A
— end example
struct A { A(); };
struct B: public virtual A { };
struct C: public A, public B { C(); };
C::C(): A() { } // ill-formed: which A?
— end example
struct C {
C( int ) { } // #1: non-delegating constructor
C(): C(42) { } // #2: delegates to #1
C( char c ) : C(42.0) { } // #3: ill-formed due to recursion with #4
C( double d ) : C('a') { } // #4: ill-formed due to recursion with #3
}; — end example
struct B1 { B1(int); /* ... */ };
struct B2 { B2(int); /* ... */ };
struct D : B1, B2 {
D(int);
B1 b;
const int c;
};
D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { /* ... */ }
D d(10); — end example
struct A {
A();
};
struct B {
B(int);
};
struct C {
C() { } // initializes members as follows:
A a; // OK: calls A::A()
const B b; // error: B has no default constructor
int i; // OK: i has indeterminate value
int j = 5; // OK: j has the value 5
}; — end example
struct A {
A() = default; // OK
A(int v) : v(v) { } // OK
const int& v = 42; // OK
};
A a1; // error: ill-formed binding of temporary to reference
A a2(1); // OK, unfortunately
— end example
struct V {
V();
V(int);
};
struct A : virtual V {
A();
A(int);
};
struct B : virtual V {
B();
B(int);
};
struct C : A, B, virtual V {
C();
C(int);
};
A::A(int i) : V(i) { /* ... */ }
B::B(int i) { /* ... */ }
C::C(int i) { /* ... */ }
V v(1); // use V(int)
A a(2); // use V(int)
B b(3); // use V()
C c(4); // use V()
— end example
class X {
int a;
int b;
int i;
int j;
public:
const int& r;
X(int i): r(a), b(i), i(i), j(this->i) { }
};
class A {
public:
A(int);
};
class B : public A {
int j;
public:
int f();
B() : A(f()), // undefined: calls member function but base A not yet initialized
j(f()) { } // well-defined: bases are all initialized
};
class C {
public:
C(int);
};
class D : public B, C {
int i;
public:
D() : C(f()), // undefined: calls member function but base C not yet initialized
i(f()) { } // well-defined: bases are all initialized
}; — end example
template<class... Mixins>
class X : public Mixins... {
public:
X(const Mixins&... mixins) : Mixins(mixins)... { }
}; — end example
struct B1 {
B1(int, ...) { }
};
struct B2 {
B2(double) { }
};
int get();
struct D1 : B1 {
using B1::B1; // inherits B1(int, ...)
int x;
int y = get();
};
void test() {
D1 d(2, 3, 4); // OK: B1 is initialized by calling B1(2, 3, 4),
// then d.x is default-initialized (no initialization is performed),
// then d.y is initialized by calling get()
D1 e; // error: D1 has a deleted default constructor
}
struct D2 : B2 {
using B2::B2;
B1 b;
};
D2 f(1.0); // error: B1 has a deleted default constructor
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); // OK: initialization of Y does not invoke default constructor of X
template<class T> struct Log : T {
using T::T; // inherits all constructors from class T
~Log() { std::clog << "Destroying wrapper" << std::endl; }
};
struct A { A(int); };
struct B : A { using A::A; };
struct C1 : B { using B::B; };
struct C2 : B { using B::B; };
struct D1 : C1, C2 {
using C1::C1;
using C2::C2;
};
struct V1 : virtual B { using B::B; };
struct V2 : virtual B { using B::B; };
struct D2 : V1, V2 {
using V1::V1;
using V2::V2;
};
D1 d1(0); // ill-formed: ambiguous
D2 d2(0); // OK: initializes virtual B base class, which initializes the A base class
// then initializes the V1 and V2 base classes as if by a defaulted default constructor
struct M { M(); M(int); };
struct N : M { using M::M; };
struct O : M {};
struct P : N, O { using N::N; using O::O; };
P p(0); // OK: use M(0) to initialize N's base class,
// use M() to initialize O's base class
— end example