Search code examples
c++11initializationcurly-braces

C++0x non-ambiguity of Generalized Initializers


I found a couple of example of the new Initializer Syntax using {...}. But the examples are quite old. I just want to cross-check -- is the current situation still as described?

In every context (especially templates), the following source fragments always are non-ambiguous -- no matter what T and v are.

  • T{v}; -- always constructs a temporary of type T and initialized it with value v.
  • T x{v}; -- initialized a variable x of type T with value v.
  • T x = {v}; -- same, because = is just optional here.
  • T a[] = {v}; -- initializes all elements of an array with the value v.
  • p = new T{v}; -- allocates an object of type T on the heap and initializes it with value v.

Therefore, it is still true, telling people "Prefer the {}-syntax, and your source code will not have different meanings, depending on what T and v are".


Solution

    • T x{v}; -- initialized a variable x of type T with value v.
    • T x = {v}; -- same, because = is just optional here.

    As far as N3291 (the last working draft before the final standard) is concerned, these are not the same for all possible v and T.

    The principle difference is the following. The first is an explicit constructor call, and it therefore may select a constructor declared explicit. The second is not an explicit constructor call (even though it will call a constructor). Therefore it cannot select explicit constructors.

    From 13.3.1.7:

    In copy-list-initialization, the candidate functions are all the constructors of T. However, if an explicit constructor is chosen, the initialization is ill-formed.

    The purpose of this is to ensure that you cannot accidentally perform an explicit conversion of a value when using copy initialization, even with {} syntax.