Uniform initialization using braces (e.g., int x {5};
) was introduced in C++11 as a way to standardize initialization across different types. It has a few advantages over using the assignment operator =
:
It prevents narrowing conversions. If you try to initialize a variable with a value that would require narrowing (like initializing an integer with a floating-point value), the compiler will throw an error:
int x = 5.5; // Compiles, but loses data
int y {5.5}; // Fails to compile
It can be used to initialize any type, including user-defined types. This makes initialization syntax more consistent across types.
Uniform initialization can be used to initialize containers and complex types in a cleaner way, especially when the initialization involves multiple values:
#include <vector>
int main() {
// Old style
std::vector<int> v = {1, 2, 3};
// Uniform initialization
std::vector<int> v{1, 2, 3};
}
Additionally, uniform initialization avoids the "most vexing parse" problem in certain situations. In the following example, the first line is ambiguous. It could be a variable x
initialized with a temporary MyClass
.
But C++ allows superfluous parentheses around function parameter declarations, so x
could be declaring a function that returns MyClass
and takes a MyClass
parameter.
The second line is unambiguously a variable.
class MyClass {};
// Is this a variable or a function declaration?
MyClass x(MyClass());
// Clearly a variable
MyClass y{MyClass()};
However, it's worth noting that uniform initialization isn't a complete replacement for the =
syntax. In some cases, like with auto
type deduction, the two forms can behave slightly differently.
Answers to questions are automatically generated and may not have been reviewed.
Learn the fundamentals of C++ programming: declaring variables, using built-in data types, and performing operations with operators