While reading the C++ Core Guidelines by isocpp I came through this section. I have seen these methods in some of the C++ code I have read so far. For example: the () have been used while initializing data fields in the constructors initialization list even for primitive types while I also seen it being used locally. Some use the {} for initialization of variables. While others use this =. I don't know what is the difference between them. I mean do they achieve the same thing and are just different styles or they have different meanings. Can anyone explain!
-
Nicolai Josuttis gave a closing keynote going over this topic at C++Now 2018, it's on YouTube.Zuodian Hu– Zuodian Hu2020-04-05 14:51:56 +00:00Commented Apr 5, 2020 at 14:51
-
Unfortunately, there is no general consensus on which style to use in which case :(Mikhail– Mikhail2020-04-07 10:00:38 +00:00Commented Apr 7, 2020 at 10:00
3 Answers
The generalized use of curly braces {} was introduced as part of C++11 standard. The important property here is that narrowing conversions are not allowed for {} initialization. e.g.
double d = 1.7789856453427678;
int a{d}; //Compile time error - value of d will not fit in a
int a(d); //ok - a is 1
int a = d; //ok - a is 1
Thus the braced {} initialization is a preferred method to write more robust code.
Comments
You may be interested in a recorded talk about this subject - of the recent history of making uniform initialization "work" in C++ (11 and later):
CppCon 2018: Nicolai Josuttis “The Nightmare of Initialization in C++”
Some bits from the end of that talk:
- Google, in their Abseil initiative, rejected trying to "convert" people to consistent use of curly-brace initialization. They therefore stick to adopting/recommending equals for "direct" initialization and parentheses when the initialization actively applies some logic. Nicolai disapproves of this approach.
- Nicolai suggests: Make the effort to change our habits, and prefer curly-brace initialization. It is better now than it used to be.
PS - This talk may also be of interest:
Core C++ 2019 :: Timur Doumler :: Initialisation in modern C++
it is more about surveying the intricacies of the different kinds of initialization (and there are quite a few!)
2 Comments
a = {2} but this seems to be messy, however, it works. Is there a better way.operator=The difference between = and braces in an initializer is pretty much non-existent. If you run into a difference, you're doing something weird or on a pre-C++14 compiler.
The main difference between {} and () is that {} doesn't perform implicit conversions, such as non-explicit converting constructors and conversion operators, changing between signed and unsigned types, and widening or narrowing integer and floating point widths. Because of this, the general advice I've heard is to prefer {} whenever possible, to avoid unexpected type conversions.