C++11 - Uniform Intialization

C++11 introduces braced initialization as the preferred way for initialization.

Existing initialization and assignment syntaxes -
1. int x(0);  //Ok, initialization in paranthesis
2. int x = 0;  //Ok, initialization using =
3. double a, b, c;
    int x(a + b + c);  //Ok, sum of double's may not fit an int, the sum is then truncated
    int x = a + b + c;  //Ok, same as above
4. string s;  //Ok, default ctor call for string class
5. string s("init");  //Ok, initialize s
6. string s();  //this is not initialize with default value, rather it declares a function named s which returns a string
7. string s2 = s1;  //Ok, copy ctor is used (not assignment operator)
8. s3 = s2;  //assignment operator
9. class ABC {
      private:       //initializing non-static data members of the class
        int x = 0;  //Ok
        int y(0);    //error
    };

Braced initialization solves these issues and brings consistency -
1. int x{0};  //Ok, initializer in braces
2. int x = {0};  //Ok, same as above
3. double a, b, c;
   int x(a + b + c);  //Error, narrowing not allowed
4. string s{};  //Equivalent to #4 above
5. string s{"init"};  //Equivalent to #5 above
6. string s{};  //No longer declares a function, rather same as #4 above
7. class ABC {
     private:
       int x{0}; //same as #9 above
       int y{0};
   };

Additionally, braced initialization can be used to initialize uncopyable objects -
std::atomic<int> x{0};
std::atomic<int> x(0); //Ok
std::atomic<int> x = 0; //Error

Braced initializers can lead to confusion when std::intializer_list constructors are involved. Example -
class ABC {
  public:
    ABC(int i, int j);
    ABC(std::initializer_list<int> k);
};
ABC(1, 2); //calls the first ctor
ABC{1, 2}; //calls the second ctor