devxlogo

Sequence Constructors Add C++09 Initialization Syntax to Your Homemade Classes

Sequence Constructors Add C++09 Initialization Syntax to Your Homemade Classes

previous 10-Minute Solution demonstrated the new initialization rules of C++09, which enable you to initialize standard containers (among the rest) in the following manner:

vector  scores = {89, 76, 98, 93}; //C++09

A new constructor type called a sequence constructor makes this syntax possible. The following sections will show how to enable the ={val1,val2,…} initialization syntax by adding a sequence constructor to your homemade classes.


Unlike C++09 Standard Library containers, your homemade container classes don’t support the new initializer list syntax.


Adding a sequence constructor to your homemade container classes will allow you to initialize instances of those classes similarly to the new initializers in the C++09 Standard Library containers.

I Want C++09 Containers’ Easy Initialization

Suppose you designed a polymorphic container class with certain operations that C++09 standard container classes don’t support. In all other aspects, however, your homemade container has the same interface as a standard container:

template  class MyVector{ T* elements; size_t n;public: virtual void reserve(size_t n); //polymorphic T& operator[] (int idx); size_t size() const;//...};

Here’s the snag. Unlike with standard C++09 container classes, populating a MyVector object in your homemade container is an arduous task. You first need to default-construct MyVector and then call push_back() or assign(). The following code demonstrates the difference between standard C++09 containers and homemade containers:

//easy initialization of a standard C++09 container  std::vector  vi={5,6,7,8}; //alas, "initializing" MyVector is tedious and bug proneint arr[]={0,2,4,8}; MyVector  vi;  vi.assign(arr, arr+4);

Now suppose you want MyVector to support the same convenient initialization syntax that C++09 containers provide. What is the secret ingredient that C++09 containers use to enable such easy initialization? Answer: Sequence constructors.

Sequence Constructors, The Secret Ingredient

Standard containers inherit their convenient initialization syntax from the newly added sequence constructors. A sequence constructor takes a single argument of type std::initializer_list, where initializer_list is a new template defined in the C++09 header . This template converts a sequence of values of type T into an array of T. That array (henceforth referred to as the range) is then used to populate the sequence constructor’s object. Here’s an example of a class with a sequence constructor:

#include struct C{ //initialize C with doubles C(std::initializer_list); };//usageC c1={1.5,0.99,23.45,-1.87};

Before continuing with the implementation of MyVector’s sequence constructor, an explanation of how initializer_list performs its magic may be helpful. It’s much simpler than you think!

Inside initializer_list

Initializer_list has two constructors and three member functions that grant access to its range:

template class initializer_list {//private data members: a pointer + size, or two pointerspublic: //constructors:constexpr initializer_list(const T*, const T*); //[first,last)constexpr initializer_list(const T*, int);//[first,first+size) //accessing the range constexpr int size() const; //number of elementsconstexpr const T* begin() const; //first element constexpr const T* end() const; //one-past-the-last element};

Put simply, initializer_list transforms a random number of values into a valid STL range by creating an array that contains copies of those values.

The Finishing Touches

Thus far, adding a sequence constructor to MyVector has involved the following:

  1. An initializer_list object silently intercepted an initializer list of the form ={5,6,7,8}; and transformed the values between the braces into a valid range.
  2. A sequence constructor initialized its object by accessing the range using the size(), begin() and end() member functions of initializer_list.
  3. Because initializer_list‘s member functions are declared constexpr, the compiler can optimize the sequence constructor considerably.

MyVector’s sequence constructor ultimately looks like this:

template class MyVector {public: //newly-added sequence constructor  MyVector(initializer_list s)  {  n=s.size()  elements = new T[n];  std::copy(s.begin(),s.end(),elements); }//...};

Having furnished MyVector with a sequence constructor, you can now initialize it as you would any standard C++09 container:

MyVector  vi={1,3,5,7,11};

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist