Three things to take away:
- Prefer initializing variables when they are created.
- Brace initialization uses
{}and is the modern default style. - Brace initialization rejects narrowing conversions, which helps catch mistakes at compile time
Definition, assignment, and initialization
Defining a variable is called … definition.
Giving a variable a value is called assignment.
Initialization merges these two instructions into one statement. E.g. int x { 11 };
This is the modern way of variable initialization.
This is because the creator of C++ and a C++ expert said so. See ES.23 under ES: Expressions and Statements
The historical way is via copy-initialization. E.g. int x = 11;
Copy-initialization has lost support in modern C++ due to being less efficient than other forms of initialization for some complex types.
Brace initialization {}
The syntax is clear. When you see curly braces, you immediately recognize that list initialization is occurring. Additionally, it’s used with other types such as std::string and structs. Thus, adopting brace initialization standardizes the syntax across a codebase.
std::string name { "Ada" };
std::vector<int> values { 1, 2, 3, 4 };
Other benefits:
- Allows us to more cleanly initialize multiple variables in a single line
int x = 5, y = 11, z = 12; // Standard initialization
int x{5}, y{11}, z{12}; // List initialization (Uniform Initialization)
2. Used to cleanly initialize a struct
// Struct definition
struct Player {
int id;
double health;
int score;
};
// Let's list initialize our struct
Player hero{1, 95.5, 1200};
// Traditional way is:
Player p;
p.id = 1; p.health = 95.5; p.score = 1200;
The major advantage: no narrowing conversions
A special advantage of list-initialization is it forbids narrowing conversions. This is
A narrowing conversion is a conversion that may lose information.
For example:
int x { 4.5 };
This does not compile, because there is a mismatch between types.
The compiler catches the mistake immediately.
With copy initialization, this kind of conversion may be accepted by some compilers, often with a warning:
int x = 4.5; // x becomes 4 on many compilers
That is risky. The value 4.5 silently becomes 4.
Brace initialization prevents this, therefore making our programs more robust.