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...
}