C++ Programming: Using Initializer Lists And Sequence Constructors in C++0x | CodeGuru

C++ Programming: Using Initializer Lists And Sequence Constructors in C++0x

Introduction C++03 initialization is inconsistent and lacking. For instance, it doesn’t let you initialize POD arrays that are class members and POD arrays allocated using new. The limitations of C++03 initialization rules become more noticeable when you need to initialize a container object. Usually, you’re forced to use a cumbersome loop as a workaround: […]

Written By
CodeGuru Staff
CodeGuru Staff
Apr 23, 2010
3 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Introduction

C++03 initialization is inconsistent and lacking. For instance, it doesn’t let you initialize POD arrays that are class members and POD arrays allocated using new. The limitations of C++03 initialization rules become more noticeable when you need to initialize a container object. Usually, you’re forced to use a cumbersome loop as a workaround:

<code>
std::vector<int> vi;
for (int i=0; i<3; i++)
 vi.push_back(i);
</code>

This is inefficient and very inconvenient.

Fortunately, the C++0x standard changed the rules of initialization. C++0x now lets you initialize almost every object, including STL containers, using the brace notation ={…}. In the following sections I will show you how to to initialize objects, arrays, dynamically allocated arrays and STL containers using the C++0x initialization notation. I will then examine the underlying mechanism that makes the brace initialization of containers tick.

Initialization with Class

In June 2008 the C++ standards committee voted into the Working Draft a new proposal for uniform initialization. Generally speaking, you can now use the brace notation to initialize objects, containers, dynamically allocated arrays and array members in a class.

First, let’s see how the new initialization notation is used with an object that has a user-defined constructor:

<code>
class A
{
int a;
int b;
public:
 A(int k, int l): k(a), l(b) {}
};
</code>

In C++03, you use the following syntax:


A a(0,0);

In C++0x you can also use braces to achieve the same effect:

<code>
A b ={0,0}; //allowed only in C++0x
</code>

Classes that have an array member prove to be a serious problem in C++03 as far as initialization is concerned. Consider:

<code>
class D
{
int n[3];
public:
 D() {n[0]=0; n[1]=1; n[2]=2;} //tedious
};
</code>

With the new rules you can initialize n elegantly like this:

<code>
class D
{
int n[3];
public:
 D(): n{0,1,2} {}//only in C++0x
};
</code>

Similarly, it’s now possible to initialize a dynamically-allocated array:

<code>
int* p = new int[5] {1,2,3,4,5};//only in C++09
</code>

Advertisement

Initializing Containers

In C++03, you’d typically “initialize” containers with a loop of repeated push_back() calls:

<code>
std::vector<int> vi;
for (int i=0; i<3; i++)
 vi.push_back(i);
</code>

This is inefficient and inconvenient. It’s time to bid push_back() loops like the one above goodbye. Here’s how you initialize vectors in C++0x:


<code>
//C++0x only
std::vector<int> vi={0,1,2};
std::vector<double> vd={0.,1.5,2.99};
</code>

Similarly, initializing a map has never been easier:

<code>
map<string, string> VIP_agents_phonebook = //C++0x only
 { {“Black Eyes Peas”, “+1 (212) 567-8900”},
   {“Beyonce”, “+1 (212) 555-0987”}};
</code>

How It Works

Don’t let the brace notation mislead you. When you initialize a vector like this:

<code>
std::vector<int> vi={0,1,2};
</code>

The compiler silently transforms this code into a constructor call. That constructor initializes vi at runtime. The C++0x Standard Library now furnishes its containers (and several other standard class templates such as std::pair) with what is known as a sequence constructor. A sequence constructor is one that takes a single parameter of type std::initializer_list. Here’s an example of class with a sequence constructor:

<code>
class E
{
  //accept a variable no of int’s as initializer
 E(initializer_list<int>);
};
//usage
E prime_list={2,3,5,7,11};
E another_prime_list={13,17};
</code>

The sequence constructor lets you initialize an object with an arbitrary number of initializers known as an initializer list. std::initializer_list<T> is a standard class template defined in the new header <INITIALIZER_LIST>. std::initializer_list transforms a sequence of initializers of type T into an array T[n] (where n is the actual number of initializers enclosed in braces) and uses that array to initialize its object.

The initializer_list class template has three member functions that grant access to the sequence of initializers:

<code>
template<class D> class initializer_list
{
//implementation (pair of pointers or pointer + length)
public:
  //constructors
 initializer_list(const D*, const D*); // [first,last)
 initializer_list(const D*, int); //[first, first+length)
  //access to the sequence
 int size() const; // no of elements
 const D* begin() const; // first element
 const D* end() const; // one-past-the-last element
};
</code>

The sequence constructor of std::vector may look like this:

&lt;code&gt;
template&lt;class T&gt; class vector
{
 T* elem;
 size_t n;
public:
vector (initializer_list&lt;T&gt; seq) //sequence ctor
{
 n= seq.size();
 reserve(n);//allocate space for n elements
 &nbsp;//copy the initializers into the vector
 uninitialized_copy(seq.begin(), seq.end(), elem);
}
// … the rest as before
};
&lt;/code&gt;

Advertisement

Conclusion

Presently, few compilers (including GCC 4.4) support initializer lists for STL containers. After the recent approval of the Final Committee Draft at the Pittsburgh meeting in March 2010, other vendors are expected to implement the uniform initialization notation and initializer lists soon.

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.