Overview: C++ Gets an Overhaul

en years after the ratification of the first ISO C++ standard, C++ is heading for no less than a revolution. C++0x, the new C++ standard due in 2009, brings a new spirit and new flesh into the software development world. Brace yourself for state-of-the-art design idioms, even better performance, and a plethora of new features such as multithreading, concepts, hash table, rvalue references, smarter smart pointers, and new algorithms. No doubt you’ll find a lot to like in C++0x!

New Core Features
The two most important features of C++0x are concepts and concurrency support. Concepts enable programmers to specify constraints on template parameters, thus making generic programming and design immensely simpler and more reliable (see Douglas Gregor’s excellent introduction to concepts). Variadic templates, template aliases (also called template typedefs), and static_assert—though not directly related to concepts—will also make the use of templates in generic libraries more intuitive, flexible, and less error prone.

The importance of a standardized concurrency API in C++ can’t be overstated: As multicore processors are becoming widespread, you simply can’t afford to remain stuck in the single-threaded era, or compromise on platform-dependent APIs. At last, there’s a portable, standardized and efficient multithreading library for C++. To get a glimpse of the new concurrency facilities of C++0x, you’re welcome to read Anthony Williams’ brilliant introduction to multithreading in C++0x. You can find additional info about thread-local storage here.

Rvalue references are yet another silent revolution. While most users will probably not even know they exist (read my interview with Bjarne Stroustrup), rvalue references enable library designers to optimize containers and algorithms by implementing move semanticsand perfect forwarding easily, thus reducing unneeded copy operations.

Automatic type deduction is made possible by the new keywords auto and decltype which deduce the type of an object from its initializer and capture the type of an expression without having to spell it out, respectively. Adding auto and decltype also paves the way for a new function declaration syntax. The function’s return type appears after the ->sign:

auto func(int x)->double {return pow(x);}

Lambda expressions and closures are another prominent feature of C++0x. A lambda expressionis a nameless function defined at the place where it’s called. It is similar to a function object except that the programmer is rid of the burden of declaring a class with a constructor, defining an overloaded () operator and an instantiating a temporary object of that class—this tedium now becomes the compiler’s job. Here’s an example of a lambda expression:

//a lambda expression is used as an argumentmyfunc([](int x, int y) -> int {return  x+y;} ) 

The lambda expression is indicated by the lambda introducer [] followed by a parameter list in parentheses. The optional return type comes next, following the ->sign. Finally, the lambda block itself is enclosed in braces.

Convenience Features
Some C++0x features are meant to simplify recurring programming tasks and minimize boilerplate code. Most of these “convenience features” were borrowed from other programming languages. These convenience features include:

Listing 1demonstrates these features.

C++0x also removes some embarrassments from the language. For example, C++03 has at least three different forms of initialization:

int x=0;int x(0);int y[2]={1,2};

C++0x defines a unified initialization notation which can even be used in the declaration of dynamically allocated arrays:

int* a = new int[4] {1, 10, 20,95 };vector vs={"ab","cd","ef"};class S { int arr[3];public:  S() : arr{ 1, 2, 3 } {}};

More Control in Your Hands
Certain new core features are meant to provide a standardized and uniform mechanism for controlling the compilation and execution environment programmatically. For example, take memory alignment. In C++03, you have to resort to compiler-dependent, non-portable hacks if you want to override the default alignment of your data. C++0x introduces two new operators: alignof and alignasthat query and override the alignment requirements of your data, respectively:

alignas (16) class Session{ long long timestamp; int authorizations; bool active; //...};cout<< alignof(Session) <

The C++98 rules regarding constant expressions force implementers to use low-tech macros instead of inline functions to ensure compile-time evaluation of constant expressions. This issue, and other limitations of C++98 constant expression rules, have led to the formation of a generalized constant expression mechanism in C++0x. Unlike const, the new constexprkeyword guarantees that the expression it qualifies can be used as a constant expression for example, in an array declaration:

const int y=func(); //dynamic initializationint buff[y]; //error, y isn't a compile-time constantconstexpr int f(int x){  return x * x; } //mandatory compile-time evaluation int arr[f(3)]; //OK, array's size is 9

Generally speaking, constexpr tells the programmer that a certain expression or object is evaluated and initialized at compile-time, as opposed to constwhich merely states that the object in question shall not change its state after initialization.

The onerous problem of undesirable implicit conversions that occur with C++98 conversion operators has also been addressed in C++0x. Up until now, programmers and library writers have had to rely on hacks such as the indirect conversion idiom to reduce the risk of undesirable conversions. In C++0x, you can declare conversion operators as explicit, thus gaining tighter control over the type of conversions that are permitted.

Compatibility with Other Standards
C++0x enhances compatibility with other independent International Standards. The first set of additions is designed to bring the C++ in closer agreement with the ISO/IEC 9899:1999 Standard C (C99 for short). C++0x compatibility with C99 consists of several new header files, among the rest:

  • : The C99 complex arithmetic library
  • : The floating point environment and support for the IEEE-754 floating point arithmetic
  • : The C99 integral types functions and macros

The influence of the recent Unicode 4.0 standard is also reflected in C++0x. C++98 defines a wide char type called wchar_t, that has an implementation-defined size. In the mid-1990s, it was assumed that wchar_t would be sufficient for supporting Unicode but this turned out to be a false hope. The unspecified size of wchar_t prohibits portable UTF encoding in C++98. C++0x solves this problem by introducing two new character types with standardized sizes: char16_t and char32_t that are specifically designed to support portably all the Unicode 4.0 codesets and encoding schemes (UTF8, UTF16 and UTF32). Obviously, some supportfor Unicode strings in its Standard Library will be available too.

The C99 standard also introduced long long for handling 64-bit integers. C++0x fixes this incompatibility at last by adding long long and unsigned long long to its list of fundamental types. Similarly, the C++0x Standard Library defines new long long overloads of the math functions and appropriate std::complexspecializations.

Library Extensions
The number of C++0x Standard Library extensions is quite overwhelming. I will list here only the more prominent extensions.

A new library for manipulating regular expressions is defined in the C++0x header. Regular expression support has been noticeably lacking in C++—especially among web programmers, designers of XML parsers, and other text-processing applications.

Back in 1997, time constraints didn't allow the standards committee to include hash tables in the first C++ standard. The new C++ standard fixes this by adding four new unordered (hash) containers: std::unordered_map, std::unordered_multimap, std::unordered_set, and std::unordered_mutiset.

Perhaps the most popular Standard Library extension is the set of new smart pointer classes: std::tr1::shared_ptr and its little known sibling, std::tr1::weak_ptr.

The class template std::tr1::array wraps a built-in array with a standard container's interface. Similarly, a tuplegroups an arbitrary number of objects of unrelated types in single, container-like object. With respect to algorithms, 11 new algorithms were voted into draft standard in June 2008. Some of these algorithms fill holes in the C++98 standard, whereas others simplify common tasks. Here are some of them:

  • all_of( first, last, pred): This returns true if all elements in the range satisfy the predicate pred
  • any_of( first, last, pred): This returns true if any element in the range satisfies pred
  • copy_n(first, n, result): This copies n elements into the result
  • iota( first, last, value): For each element in the range, this assigns value and pre-increment value by ++value
  • none_of( first, last, pred): This returns true if none of the elements in the range satisfies pred

Finally, the rangeand subrange class templates of C++0x bundle pairs of iterators, thus significantly simplifying certain sequence operations and compacting the signatures of many popular algorithms.

The Road Ahead
The vast number of new features forces the committee to work at an incredible speed. A clear statement of intent was made to complete work on the new standard at the San Francisco meeting of September 2008 in order to achieve publication in 2009. To meet this ambitious timetable the plan is to vote out a feature complete Working Draft at the next meeting. A Final Committee Draft will be issued from the following meeting, allowing at least a minimal time for review and "integration testing" of the new features—particularly a conceptualized Standard Library.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Related Posts