C++11 – Part 5: Initialization

C++11 bring with it a great improvement in initializing data. I’ll first cover initializing containers and then move on to more general variable initialization.

Initializer lists
Arrays could always be initialized using C style initialization:

int arr[] = {1,2,3,4,5};

But, that syntax could not be used with containers. That seemed a bit silly given that (e.g.) a std::vector is just a fancy array, so losing features that arrays have is bad. C++11 allows this type of initialization for all containers. You can also add this type of initialization for any of your classes, or even as an argument to a function. This works by the {} initialization works is that it creates an object of a new class std::initializer_list. So for this to be used in your class, you just need to add the relevant constructor. E.g.:

template<class t> class Vec
public:
  Vec(std::initializer_list i)
  {
  size = i.size();  // set the size of the array in Vec
  reserve(size);    // allocate the required space in the array
  uninitialized_copy(i.begin(), i.end(), array);
  }
// ...

Defining a function that takes an initializer list as an argument is similarly easy.

Uniform Initialization
In C++03, initialization of variables was all over the place. Initializer lists improve on that somewhat, but C++11 takes it one step further. Now everything can be initialized in much the same way. Some cases taken straight from the proposal:

  • Variable initialization; e.g., X x {v};
  • Initialization of a temporary; e.g, X{v}
  • Explicit type conversion; e.g. x = X{v};
  • Free store allocation; e.g. p = new X{v}

There are a few situations where I see this as being particularly useful:

1. Initialisation of dynamically allocated arrays:
int *p = new int[3]{1,2,3};

2. Initialization of an array member variable:
class C {
  int a[3];
public:
  C(int x, int y, int z) : a{x, y, z} { /* ... */ };
};

3. Implicitly initialize objects to return:
return {foo, bar};

4. Implicitly initialize a function parameter:
f({foo, bar});

There are some slight traps with the use of this initialization syntax with classes using constructors. For example, take the class C in case #2 above. The following two statements are equivalent:

C c1(1,2,3);
C c2{1,2,3};

However, for std::vector, which is able to be initialized using an initializer list, the following are different:

std::vector v1(10,3); // vector of length 10
std::vector v1{10,3}; // vector of length 2

3 thoughts on “C++11 – Part 5: Initialization

  1. How do you initialize this:

    template
    class Array
    {
    private:
    T array_[N];

    public:
    Array(const T & value)
    : array_( /* initialize every thing with value */ )
    {
    }
    };