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:
int i = { 0 };
POD pod = { 0, 1, 2 };
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.
struct Base { };
struct Class : Base
{
    int mem{ 0 };  // init non-static data member
    Class(int i)
    : Base{}   // init base class
    , mem{i}   // init member
    {
      int j{i};   // init local var
      int k = int{0};  // init temporary
      f( { 1 } );  // init function arg
      int* p = new int{1};  // new init
      // int k(int());  // most vexing parse, declares function
      int k{ int{} };   // ok, declares variable
      int i[4]{ 1,2,3,4 };   // init array
    }
    Class f(int i)
    {
      return { i };   // init return value
    }
};
Class c{1};   // init global var
Most of the initializations above declare an int or array of int but the same syntax can be used to call a constructor for a class type (like the two lines that construct a Class variable)
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_list class template.  A constructor that takes a std::initializer_list argument can be passed an arbitrarily-long list of values, which the constructor can iterate over via begin() and end() member functions of the std::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 than Map 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 a std::initializer_list e.g.
// attempts to create vector of 5 elements, [1,1,1,1,1]
// but actually creates a vector with two elements, [5,1] 
std::vector<int> v{ 5, 1 };
This doesn't call the vector(size_type, const int&) constructor, instead of calls the vector(initializer_list<int>) constructor.
List assignment
In C++11 you can use "list-assignment"
- when assigning to a scalar type, if the braced-init-list has a single element that is  convertible (without narrowing) to the variable's type (see [expr.ass]/9)
- 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 to- T, e.g. for the- std::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.
 - struct A {
  int i;
  int j;
};
struct B {
  B& operator=(const A&);
};
int main() {
  B b;
  b = { 0, 1 };
}
 - On the last line of - mainthe braced-init-list will be implicitly-converted to a temporary- Athen the assignment operator of- Bwill be called with that temporary as its argument.