Guidelines For Initialisation

Guidelines For Initialisation

27 Aug 2018    

This is a combination of Herb Sutter’s GotW #1 and Abseil Tip #88.

There are about 18 ways to initialise a variable in C++. Especially given C++ 11’s uniform initialisation syntax it’s getting pretty complicated. Use the following guidelines when trying to initialise a local or member variable:

Use {} Syntax With =

Using the uniform initialisation syntax avoids a few C++ pitfalls, namely the most vexing parse and narrowing conversions. Combined with the assignment operator it ensures that it won’t accidentily call un-intended constructors and is especially useful for list initialisation. Similarly, it should be used for aggregate initialisation of structs as well.

std::vector<int> numbers = {1, 2, 3, 4};
auto numbers = std::vector<int>{1, 2, 3, 4};

auto copyString = std::string{otherString};

SimpleStruct triv = {val1, val2};

Use () If Using a Specific Non-Default Constructor

If you’re calling a specific constructor with specific behaviour that does not use an initializer list, then use the usual parentheses syntax.

auto const resizeNum = 15;
auto const defaultVal = 42;

// Both lines don't have to use =
auto numbers = std::vector<int>(resizeNum, defaultVal);

auto symbol = Symbol(display_prop, texture);

Use {} Without = If Above Options Don’t Compile

If a constructor is marked explicit or is non-copyable / non movable then you can initialize without an assignment statement. C++ 17 alleviates a few of these concerns and should allow for using = even if it is non-copyable.

NonCopyType local_var{42, other_variable}; // OK

// Both lines below are weird cases
// Do do that
auto number{42};
auto value = {42};