Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properly initialising variables in modern C++ (C++11 and above), using () or {}?

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.

like image 359
Ray Avatar asked Apr 24 '15 15:04

Ray


People also ask

What is the correct way of initializing the variable?

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.

Can we initialize variable in C?

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.

What values should you use for initialization?

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.


1 Answers

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 by std::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.

like image 105
Galik Avatar answered Sep 22 '22 23:09

Galik