std::vector and C++'s braced initialization

The new versions of C++ (starting from C++11) include a unified initialization syntax based on braces. In most of the cases it offers a more elegant and unified way of initializing objects. Examples of its usage are as follows:

std::string name{"Michael Scott"}; 
MyClass obj{}; // default constructor

Braced initialization can also be used in constructors to initialize class members:

MyClass::MyClass(const Something& value) : member{value} {
    // Additional operations ...
} 

When it comes to be widely-used std::vector, braced initialization might be a source of confusion. It is typical that one knows the initial capacity of a vector and wants to set all elements to some constant value. The traditional way to do it is as follows:

std::vector<int> x(100, 0); // Create vector with 100 zeros

One might be tempted to write an expression as such:

std::vector<int> x{100, 0}; 

However, because std::vector has one of the constructors based on std::initializer_list, the rule is that that particular constructor will always be used if braced syntax is used. As such, the latter snippet will create a 2-element vector with values of 100 and 0. This will actually be the case even if we are talking about std::vector<double>.

A more unambigous way to specify ininialation based on std::initializer_list would be with using the equals sing:

std::vector<int> x = {1, 2, 3, 4, 5}; 

A rule of thumb is thus to prefer using braced initialization in most cases, but use (...) and = {...} when working with std::vector and other classes containing a std::initializer_list constructor.

Read also: