Skip to content

Uniform initialization

Uniform initialization

int num {4711};
auto num {4711};

this is “direct list initialization”, works for all types, detects narrowing errors, always prefer this type of initialization over:

auto num (4711);
auto num = 4711;
auto num = {4711}; // is a std::initializer_list<int> 

Aggregate initialization

struct Base { int m_num; std::string m_name};
struct Derived : public Base {bool m_flag};
Derived d {{4711,"SomeName"}, true};

Possible aggregates are: array, class/struct with public data and without user-declared constructor.

Attention: Possibility to forget correct initialization of fundamental types:

Derived d{{}, true}; // => correct initialization with 0, "", true
Derived d{};         // => correct initialization with 0, "", false
Derived d;           // => values for m_num and m_flag are unspecified!

To avoid uninitialized fundamental types provide a constructor initialization for those data members within class header or always use list initialization {}.

Named initialization

Base b1 {.m_num=4, .m_name="Frank" };
Base b2 {.m_name="Joe"}; // members can be omitted (and may stay uninitialized)
Base b3 {.m_name="Fred", .m_num=4 }; // ERROR: always use the order of declaration