How to always initialize properly?

99 views Asked by At

With C++11 the Unified Initialization has been introduced and I got the impression that {} is now a quite safe initialization for all cases (when allowed). But I just noticed, that I mistaken.

What is a safe form of initialization for all types? Baring classes with deleted/private default c'tor, or course.

Details for some type-kinds

Here is a built-in:

int u;          // evil, x will be un-initialized
int v{};        // nice value-initialization, as far as I know.
int w={};       // nice value-initialization, right?
int x={0};      // proper initialization, not suited for other types though
int x=0;        // proper initialization, also not suited

But with an aggregate like tm

#include <ctime>
tm birth1{};    // evil. nothing initialized.
tm birth4=tm(); // yes! nice value-initialization.
tm birth2 ={};  // evil. nothing initialized
tm birth3 ={0}; // evil, only first member init

but with C-arrays

int data1[9] ={};  // evil. nothing initialized.
int data1[9] ={0}; // proper (value?)-initialization of all elements

And what with classes beyond aggregates with a compiler-generated default-c'tor?

struct Widget {
    std::string name;
    int val;
};
Widget w1;    // w1.val will be uninitialized
Widget w2{};  // w2.val will be uninitialized
Widget w3 = Widget{}; // ??? will w3.val be value-initialized?
Widget w4{0}; // an error, or course.

Did I forget an important kind?

A template that works for all?

As an extended question I wonder if there is a proper/good/any way to write a template function that returns a properly initialized object for all types that can be initialized in that way:

template<typename T>
T init() {
    return T{};
    // or 'T t = T{}; return t;'
    // or...
}
0

There are 0 answers