devxlogo

Uniform and Convenient Initialization Syntax

Uniform and Convenient Initialization Syntax

lass objects use a constructor argument list as their initializer, aggregates use braces, strings use literal text with double quotes, and containers use yet another form of initialization. These diverse initialization forms confuse users and make template code more obfuscated, not to mention the fact that C++98 doesn’t provide a means for initializing member arrays and dynamically-allocated arrays. Learn how C++0x’s new initialization notation fixes these embarrassments, making your code safer and easier to read and maintain.


C++98 initialization syntax is confusing, inconsistent, and lacking.


Use the new, uniform C++0x initialization form for all types of objects and arrays.

Against All PODs
An aggregate is:

  • A POD struct, class, or unions
  • An array of a POD type

The initializer of an aggregate looks like this:

struct Point1{  int x;  int y;  //...};Point1 p1 = {1,2}; //aggregate initialization 

However, when you deal with a class that has a constructor, you must use a different initialization form:

class Point2 {public:  Point2( int x, int y );  // ...};Point2 p2(1,0);

This diversity makes the design of generic code difficult because a template that initializes an arbitrary object must know whether the object is an aggregate or a class with a constructor.

Things get messier when you use container objects. Take for example a vector of strings. Today, you have to “initialize” such a container by hand:

vector vs;vs.push_back("ab");vs.push_back( "cd");vs.push_back("ef");

Alternatively, you can create an array of strings and use it to initialize the container:

string arr[] = {"ab", "cd", "ef"};  // initialize the container with an existing arrayvector vs( arr, arr+3); 

This is highly inefficient, error-prone, and pretty disgusting.

Initialization Loopholes
Agreed, C++98 initialization is messy. In addition, it has two known loopholes. You have no means of initializing arrays that are data members nor can you initialize dynamically-allocated arrays of POD types. As a workaround, programmers assign a value to each element manually:

//member array class C {  int arr[3];public:  C() { arr[0]=1; arr[1]=2; arr[2]=3; }};//dynamically allocated arrayint* p = new int[3];p[0]=1;p[1]=2;p[2]=3;

Imagine if you had to “initialize” an array with thousands of elements in this way! This is not to mention the risk of accidentally skipping elements or initializing elements that don’t exist. Fortunately, C++0x has a much better solution.

Change We Need
In June 2008, the C++ standards committee accepted a new proposal for a uniform initialization form for class objects, arrays, aggregates, and so on.

Generally speaking, C++0x allows you to use braces more liberally. For example, you can initialize an object that has a user-declared constructor like this:

class A{int a;int b;public: A(int i, int j);};// C++0x object initializerA a ={0,0}; //equivalent to: A a(0,0);

Of course, the traditional parenthesized initializer is still valid in C++0x.

But what about containers? Say goodbye to a long list of push_back() calls. In C++0x, you can initialize standard containers easily and efficiently:

// C++0x container initializervector vs={ "ab", "cd", "ef"};map dialawhine =  { {"Alan Greenspan", "+1 (212) 5555-4321"},    {"Ben Bernanke", "+1 (212) 555-1234"}};

Under the hood, these container classes use a special constructor type called a sequence constructor (a discussion of which is beyond the scope of this article). Suffice it to say, that from an end-user perspective, these initializations just work.

The most daring change in the new C++0x initialization form is the ability to initialize two categories of arrays that have hitherto proved impregnable to initialization. Yes, I’m talking about member arrays and dynamically allocated arrays of POD types.

Here’s how you initialize an array member using the new C++0x initialization syntax:

class C {  int arr[3];public:  C(): arr{1,2,3}{} //C++0x member array initializer};

Similarly, you can now initialize a dynamically-allocated array like this:

int* p = new int[3] {1,2,3};//C++0x initializer

It’s CD Time
At present, most compilers don’t support the new C++0x initialization form. However, it won’t take long before vendors start incorporating this feature. In September 2008, the C++ standards committee approved the C++0x Working Paper as an official ISO Committee Draft (CD). You can think of the CD as a feature-complete beta. The CD is now being reviewed by all national bodies involved in the standardization process. A second review phase is planned for next year and that will bring us even closer to a Final International Draft Standard.

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