The C++ reference pages say that () is for value initialisation, {} is for value and aggregate and list initialisation. So, if I just want value initialisation, which one do I use? () or {}? I'm asking because in the book "A Tour of C++" by Bjarne himself, he seems to prefer using {}, even for value initialisation (see for example pages 6 and 7), and so I thought it was good practice to always use {}, even for value initialisation. However, I've been badly bitten by the following bug recently. Consider the following code.
auto p = std::make_shared<int>(3); auto q{ p }; auto r(p);
Now according to the compiler (Visual Studio 2013), q
has type std::initializer_list<std::shared_ptr<int>>
, which is not what I intended. What I actually intended for q
is actually what r
is, which is std::shared_ptr<int>
. So in this case, I should not use {} for value initialisation, but use (). Given this, why does Bjarne in his book still seem to prefer to use {} for value initialisation? For example, he uses double d2{2.3}
at the bottom of page 6.
To definitively answer my questions, when should I use () and when should I use {}? And is it a matter of syntax correctness or a matter of good programming practice?
Oh and uh, plain English if possible please.
EDIT: It seems that I've slightly misunderstood value initialisation (see answers below). However the questions above still stands by and large.
Generally, all variables should be explicitly initialized in their declaration. The descriptive comment is optional. In most cases, variable names are descriptive enough to indicate the use of the variable. However, provide a comment if further description is appropriate or if an initial value is unusual.
Unlike PASCAL, in C variables may be initialized with a value when they are declared. Consider the following declaration, which declares an integer variable count which is initialized to 10. Lets examine what the default value a variable is assigned when its declared.
Q: When should I initialize with { 0 } vs {}? Use an explicit initialization value if you're actually using that value. Use value initialization if the value is temporary and will be replaced.
Scott Meyers has a fair amount to say about the difference between the two methods of initialization in his book Effective Modern C++.
He summarizes both approaches like this:
Most developers end up choosing one kind of delimiter as a default, using the other only when they have to. Braces-by-default folks are attracted by their unrivaled breadth of applicability, their prohibition of narrowing conversions, and their immunity to C++’s most vexing parse. Such folks understand that in some cases (e.g., creation of a
std::vector
with a given size and initial element value), parentheses are required. On the other hand, the go-parentheses-go crowd embraces parentheses as their default argument delimiter. They’re attracted to its consistency with the C++98 syntactic tradition, its avoidance of the auto-deduced-a-std::initializer_list problem, and the knowledge that their object creation calls won’t be inadvertently waylaid bystd::initializer_list
constructors. They concede that sometimes only braces will do (e.g., when creating a container with particular values). There’s no consensus that either approach is better than the other, so my advice is to pick one and apply it consistently.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With