What is the purpose of various type initialization in C++ and what is the correct one?
int i1 = 1;
int i2(1);
int i3{};
int i4 = {1};
int i5 = int{1};
What is the purpose of various type initialization in C++ and what is the correct one?
int i1 = 1;
int i2(1);
int i3{};
int i4 = {1};
int i5 = int{1};
int i1 = 1;This is good old C style. Still works fine and is conventional in C++.
int i2(1);This is C++ style. It came about because some types need more than one argument to their constructor.
int i3{};C++11 style.
int i4 = {1};This is not conventional.
int i5 = int{1};This is not conventional. But it's supported due to the new "uniform initialization syntax" of C++11.
int i6 = {};You didn't ask about this one, but it's also valid in C++11.
int i7{1};Another bonus, this is probably the most conventional use of uniform initialization syntax in C++11.
auto i8 = int{1};Thanks to KerrekSB for this abomination, which he credits to none other than Herb Sutter. This will probably win you friends from the "No True Modern C++" camp, and alienate your coworkers who were perfectly happy with the first syntax.
auto i8 = int{1}; -- Sutter style.int i2(1) was a mistake and should always have been int i2{1} which is now known as Uniform Initialization in C++11. As for why there are so many options, it's because of this: xkcd.com/927 . The old way reminds people of C and doesn't work for certain types; the newest ways don't work with old compilers and will scare some people off (the majority of C++ programmers have probably never used C++11 Uniform Initialization).T t (1) and T t {1} will do different things. std::vector, for instance.TL;DR - Use X a1 {v}; for initialization.
To take cue from Bjarne Stroustrup himself, below is directly quoted from TCPL, fourth edition -
If an initializer is specified for an object, that initializer determines the initial value of an object. An initializer can use one of four syntactic styles:
X a1 {v};
X a2 = {v};
X a3 = v;
X a4(v);
Of these, only the first can be used in every context, and I strongly recommend its use. It is clearer and less error-prone than the alternatives. However, the first form (used for a1) is new in C++11, so the other three forms are what you find in older code. The two forms using = are what you use in C.
std::vector<int> v1(1, 2);and std::vector<int> v2{1, 2}; will do different things.type(1, 3) calls constructor of type with 2 parameters like a function call: ctor(1, 3), but what type{1, 2} does?