This question already covers what PODs and aggregates are, and provides some examples on aggregate initialization.
The question here is where can you use list initialization?
Also where can you use (in lack of a better term) list assignment?
An answer should deal with both C++03 and C++11, highlighting the differences between them.
C++03
List initialization
In C++03 you can only use list-initialization for aggregates (C++03 [dcl.init.aggr]) and scalar (C++03 [dcl.init]/13) types:
List assignment
You could not use “list-assignment” anywhere in C++03. The grammar shown in [expr.ass]/1 does not allow a braced list on the right of an assignment.
C++11
List initialization
In C++11 you can use list-initialization pretty much anywhere you can create a variable (see [dcl.init] in C++11 and [dcl.init.list]/1 which lists contexts where list-initialization is allowed) e.g.
Most of the initializations above declare an
intor array ofintbut the same syntax can be used to call a constructor for a class type (like the two lines that construct aClassvariable)As well as being valid in almost any context where you can initialize a variable, list-initialization also interacts well with another new feature of C++11: the
std::initializer_listclass template. A constructor that takes astd::initializer_listargument can be passed an arbitrarily-long list of values, which the constructor can iterate over viabegin()andend()member functions of thestd::initializer_list. The main benefit of this new feature is that it allows you to initialize a container with a set of elements, e.g.vector<int> v{ 0, 1, 2, 3, 4, 5 }rather than constructing the container and then inserting values.List-initialization can also be used for elements within a braced-init-list, allowing nested list-initialization e.g.
Map m{ {a, b}, {c, d} }rather thanMap m{ Map::value_type(a, b), Map::value_type(c, d) }The only time list-initialization doesn’t do the right thing is when trying to construct a class type by calling a constructor if the class has another constructor taking a
std::initializer_list, as list-initialization will always prefer the constructor taking astd::initializer_liste.g.This doesn’t call the
vector(size_type, const int&)constructor, instead of calls thevector(initializer_list<int>)constructor.List assignment
In C++11 you can use “list-assignment”
when the left operand of the assignment is a class type with a user-defined assignment operator, in which case the braced-init-list is used to initialize the argument of the operator (see [expr.ass]/9). This includes both cases like
operator=(std::initializer_list<T>)where the elements of the braced-init-list in the right operand are convertible toT, e.g. for thestd::vector<int> vabove,v = { 1, 2, 3 }will replace the container’s contents with [1,2,3] and when the braced-init-list can be implicitly-converted to the operator’s argument type, via a suitable constructor e.g.On the last line of
mainthe braced-init-list will be implicitly-converted to a temporaryAthen the assignment operator ofBwill be called with that temporary as its argument.