Browse DevX
Sign up for e-mail newsletters from DevX


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

You can initialize C++09 Standard Library containers with a list of initializers, but what about your homemade container classes? Sequence constructors enable you to initialize instances of your homemade classes in a similar fashion.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

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<T>, where initializer_list<T> is a new template defined in the C++09 header <initializer_list>. 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 <initializer_list> struct C { //initialize C with doubles C(std::initializer_list<double>); }; //usage C 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<typename T> class initializer_list { //private data members: a pointer + size, or two pointers public: //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 elements constexpr 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 T> class MyVector { public: //newly-added sequence constructor MyVector(initializer_list<T> 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 <int> vi={1,3,5,7,11};

Danny Kalev is a certified system analyst and software engineer specializing in C++. He was a member of the C++ standards committee between 1997 and 2000 and has since been involved informally in the C++0x standardization process. He is the author of "The ANSI/ISO Professional C++ Programmer's Handbook" and "The Informit C++ Reference Guide: Techniques, Insight, and Practical Advice on C++."
Thanks for your registration, follow us on our social networks to keep up-to-date