MyClass a1 {a}; // clearer and less error-prone than the other three
MyClass a2 = {a};
MyClass a3 = a;
MyClass a4(a);
Why?
I couldn't find an answer on SO, so let me answer my own question.
MyClass a1 {a}; // clearer and less error-prone than the other three
MyClass a2 = {a};
MyClass a3 = a;
MyClass a4(a);
Why?
I couldn't find an answer on SO, so let me answer my own question.
Basically copying and pasting from Bjarne Stroustrup's "The C++ Programming Language 4th Edition":
List initialization does not allow narrowing (§iso.8.5.4). That is:
Example:
The only situation where = is preferred over {} is when using
auto
keyword to get the type determined by the initializer.Example:
Conclusion
Prefer {} initialization over alternatives unless you have a strong reason not to.
There are MANY reasons to use brace initialization, but you should be aware that the
initializer_list<>
constructor is preferred to the other constructors, the exception being the default-constructor. This leads to problems with constructors and templates where the typeT
constructor can be either an initializer list or a plain old ctor.Assuming you don't encounter such classes there is little reason not to use the intializer list.
There are already great answers about the advantages of using list initialization, however my personal rule of thumb is NOT to use curly braces whenever possible, but instead make it dependent on the conceptual meaning:
For one, that way I'm always sure that the object gets initialized irrespective of whether it e.g. is a "real" class with a default constructor that would get called anyway or a builtin / POD type. Second it is - in most cases - consistent with the first rule, as a default initialized object often represents an "empty" object.
In my experience, this ruleset can be applied much more consistently than using curly braces by default, but having to explicitly remember all the exceptions when they can't be used or have a different meaning than the "normal" function-call syntax with parenthesis (calls a different overload).
It e.g. fits nicely with standard library-types like
std::vector
: