8

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};
2
  • 3
    Who claimed that there was a unique correct choice? Commented May 11, 2016 at 9:09
  • 1
    If you want the value to be 0, option 3 is the correct one. Commented May 11, 2016 at 9:19

2 Answers 2

11

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.

Sign up to request clarification or add additional context in comments.

12 Comments

You forgot auto i8 = int{1}; -- Sutter style.
@KerrekSB: Great, added that!
@FrankPuffer: Arguably the original C++ way of 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).
Note that there are situations in which T t (1) and T t {1} will do different things. std::vector, for instance.
@CinCout No, it won't. auto i8 = 1 is int, auto i9 = 1LL is long long, auto i10 = 1UL is unsigned long, etc. Well, it is confusing, I know.
|
4

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.

2 Comments

Unfortunately the uniform initialization is not fully uniform. std::vector<int> v1(1, 2);and std::vector<int> v2{1, 2}; will do different things.
So if I have s type with 2 params in constructor, the type(1, 3) calls constructor of type with 2 parameters like a function call: ctor(1, 3), but what type{1, 2} does?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.