== Why is this an issue? C+11 introduced “Uniform initialization”/"list initialization". It is a way to initialize an object from a braced-init-list. This adds a third way to initialize objects in {cpp} on top of parentheses and equal signs. ---- int a{1}; // braces initialization int b(1); // parentheses initialization int c=1; // equal sign initialization ---- “Uniform initialization” was introduced to address the confusion of the many initialization syntaxes in {cpp} and to give a syntax that, in concept, can be used in all initialization scenarios. It helps to: * Initialize container in a way that wasn't possible before: ---- // Before std::vector v; v.push_back(1); v.push_back(2); // After std::vector{1,2,3}; ---- * Avoid narrowing: ---- double d=2.5; int i{d}; // Compilation error ---- * Avoid the most vexing parse: ---- class A{}; A a(); // Compilation error declares a function named a that returns A. A a{}; // Call A constructor ---- That is why “Uniform initialization” should be preferred. === Noncompliant code example [source,cpp] ---- struct A { A(int i, int j, int z) { ... } }; void f() { A a(1,2,3); // Noncompliant } struct B { A a = A(1, 2, 3); // Noncompliant }; ---- === Compliant solution [source,cpp] ---- struct A { A(int i, int j, int z) { ... } }; void f() { A a{1,2,3}; } struct B { A a{1, 2, 3}; }; ---- === Exceptions * In some situations, “Uniform initialization” has surprising behavior. for example, in constructor overload resolution, “Uniform initialization” prefers the constructor with "std::initializer_list" as a parameter if possible, even if another constructor seems like a better match. Like in the "std::vector" case, you might need to go back to parentheses in order to call the non "intializer_list" constructor: [source,cpp] ---- vector v1(5, 10); // 5 copies of the value 10 ---- * When "=" is after "auto". This might be needed to enforce deduction to initializer_list:  [source,cpp] ---- auto i1 {1}; // int with the value 1 auto i2 = {1}; // std::initializer_list with an element equal to 1 ---- * In single argument cases, "=" is okay: [source,cpp] ---- int i = 39; ---- * When the braces are after the "=": [source,cpp] ---- vector v = { 1, 2, 4 }; ---- == Resources * {cpp} Core Guidelines - https://github.com/isocpp/CppCoreGuidelines/blob/e49158a/CppCoreGuidelines.md#es23-prefer-the\--initializer-syntax[ES.23: Prefer the `{}`-initializer syntax] ifdef::env-github,rspecator-view[] ''' == Comments And Links (visible only on this page) === on 11 May 2020, 09:05:55 Geoffray Adde wrote: * The description is crystal clear! I love the summary about initialization. * In single argument cases, "=" is okay:  =>  maybe builtin single argument case ? * In some situations, “Uniform initialization” has surprising behavior. => somehow to me, it makes sense because the curly braces syntax seems to indicate initializer list. * Do we need more examples? endif::env-github,rspecator-view[]