C++11
=====

Based on Scott Meyers: Effective Modern C++


class X  { ... };

X x1;       // default constructor
X x2 = x1;  // copy constructor
x1 = x2;    // assignment



Braced initialization in C++11:
===============================

Initializing containers:

std::vector<int>  v{ 1, 2, 3 };


Normal Initialization:

int x( 0 );
int x = 0;
int x{ 0 };
int x = { 0 };   // usually the same as int x{ 0 };


Initializing (non-static) data members:

class X
{
  ...
private:
  int x{ 0 };	// ok,
  int y = 0;    // ok
  int z( 0 );   // syntax error!
};


Initializing non-copyable objects:

std::atomic<int>  a1{ 0 };  // ok
std::atomic<int>  a2( 0 );  // ok
std::atomic<int>  a3 = 0;   // syntax error!


Only { } can be used everywhere -> _uniform_ initialization



Narrowing conversions:

double d;

int i = d;   // ok, narrowing, reverse compatible
int i( d );  // ok, narrowing, reverse compatible
int i{ d };  // syntax error!



Most wexing parse:

class X { ... };

X x1(10); // constructor with int parameter
X x2;     // constructor without parameters
X x3();   // most vexing parse 
X x4{};   // ok, constructor without parameters



Auto

auto x1 = 1;     // int
auto x2(1);      // int
auto x3 = { 1 }; // std::initializer_list<int>, one element
auto x4{ 1 };    // std::initializer_list<int>, one element

auto x5 { 1, 2, 3.14 };  // syntax error! can not deduce T



Compilers prefer braced initialization. Prefer very much!

class X
{
  ...
public:
  X(int i, bool b);
  X(int i, double d);
  X(std::initializer_list<long double> il);
  operator float() const;
  ...
};

X  x1(10,true);  // X(int,bool)
X  x2{10,true};  // std::initializer_list<long double>
X  x3(10, 5.);   // X(int, double)
X  x4{10, 5.};   // std::initializer_list<long double>


X  x5(x4);       // cpy ctror 
X  x6{w4};       // std::initializer_list<long double>  w6->float->long double
X  x7(std::move(x4));   // move ctror
X  x8{std::move(x4)};   //initializer_list as x6



class Y
{
  ...
public:
  Y(int i, bool b);
  Y(int i, double d);
  Y(std::initializer_list<bool> il);

  // no conversions
};

Y y{10, 5.0};  // syntax error: requires narrowing conversion: double->bool
               // Y(int i, double d) would be exact match, but 
               // { , } will be initializer_list


Not initializer_list only when impossible

class Y
{
  ...
public:
  Y(int i, bool b);
  Y(int i, double d);
  Y(std::initializer_list<std::string> il);

  // no conversions
};

Y y{10, 5.0};  // ok: Y(int, double)



Empty brace means default contructor:

Z z1;    // default constructor
Z z2{};  // default constructor
Z z3();  // most wexing parse
Z z4({}) // std::initializer_list with 0 elements
Z z4{{}} // std::initializer_list with 0 elements



Every-day samples

std::vector v1(10,0);  // 10 elements: 0, 0, ... , 0
std::vector v2{10,0};  //  2 elements: 10, 2



Delegating constructor
======================


class X
{
public:
  X() : i_(0), k_(0) { }
  X(int i) : i_(i), k_(0) { }
private:
  int i_;
  int k_;
};


class X
{
public:
  X() {  helper(0,0); }
  X(int i) { helper(i,0); }
private:
  void helper(int i, int k) { i_ = i; k_ = k; }
  int i_;
  int k_;
};


class X
{
public:
  X() : i_(0), k_(0) { }
  X(int i) : i_(i), k_(0) { }
private:
  int i_;
  int k_;
};


class X
{
public:
  X() : X(0) { }
  X(int i) : i_(i), k_(0) { }
private:
  int i_;
  int k_;
};


int main()
{
  X  w1;
  X  w2(1);
}


class X
{
public:
  X() : X(0), k_(0) { }
  X(int i) : i_(i), k_(0) { }
private:
  int i_;
  int k_;
};

c.cpp: In constructor ‘X::X()’:
c.cpp:4:19: error: mem-initializer for ‘X::k_’ follows constructor delegation
   X() : X(0), k_(0) { }


§12.6.2/6) A mem-initializer-list can delegate to another constructor
of the constructor’s class using any class-or-decltype that denotes
the constructor’s class itself. If a mem-initializer-id designates
the constructor’s class, it shall be the only mem-initializer; the
constructor is a delegating constructor, and the constructor selected
by the is the target constructor. [...]