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".
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.