Microsoft & .NETVisual C#What's New in C++00X?

What’s New in C++00X?

Get Ready for the New C++ Language Standards!

The next C++ standard, code-named “C++00X,” is heading down the home stretch towards ratification. The goal is to have the new standard completed by 2009. As with any International Standards Organization (ISO) standard, it requires worldwide cooperation among all the member nations to be official. The most recent ISO standard, C++98, now has several years of experience and results to build from. Actually, C++98 was updated in 2003. The “00X” part of the C++00X name recognizes that this is a multi-year process and the exact completion date could vary by a year or two. Currently, it is expected to be named C++09 as of the latest report (N2336). In this article, you won’t examine the ratification process itself but rather what C++00X means to the average C++ programmer in the trenches.

The Big Picture

To understand what is afoot with C++00X, you should first take a look at the current design goals of Bjarne Stroustrup, the man considered to be the father of modern C++. Stroustrup’s highest goals are to (1) increase the utility of C++ in developing operating system (OS) and library components and (2) to make C++ easier to learn and to teach. I first saw him at the Software Development ’99 conference in San Francisco and I recall the latter point was weighing heavily on his mind. Although there are lots of “opportunities” to increase the C++ footprint in the domains of numeric computation, windowing systems, and other commonly needed application environment components, Stroustrup feels strongly that these roles are better filled by existing open source or third-party suppliers.

Rolling in the TR1

The Technical Report 1 (TR1) library extensions were approved by the ISO committee in 2005 and are expected to be part of C++00X. Indeed, according to Scott Meyer’s site, Boost has already implemented functionality that is close or identical to most of the components of TR1. Gnu’s C++ compiler (GCC) Version 4 includes most of TR1 as of this writing. A quick overview of stuff from TR1 includes:

  • Reference Wrappers
  • Smart pointers (like Boost)
  • Function Objects
    • Polymorphic Function Wrapper: Stores all callables that use a specified function call signature
    • Function Object Binders: Binds parameters to function objects
    • Function Return Types: Determines the type of a call expression
    • mem_fn: Sllows pointers to member functions to be treated as function objects
  • Metaprogramming and Type Traits: Facilitates metaprogramming by enabling queries on and transformation between different types
  • Numerical Facilities
    • Random Number Generation
    • New Mathematical Functions
  • Containers
    • Tuple Types: Like an extension of “pair” (based on Boost)
    • Fixed Size Array (as opposed to vector)
    • Hash Tables: Unordered associative containers
  • Regular Expressions: Posix-like library
  • Better C Compatibility: Matches most C99 standards

New Language Syntax and Semantics

The latest and greatest information on C++00X as it stands was released in N2336 on July 29th, 2007. Several of the improvements are of interest only to programmers who develop C++ runtime libraries and compilers, but some of them have exciting possibilities for the average developer. In the remainder of this article, you’ll look at how some widely applicable proposed improvements to C++ could make your life better; these include multi-threading.

Delegating Constructors

Problem: In standard C++, constructors are not allowed to call other constructors. The syntax to do so simply doesn’t exist, so each constructor must construct all of its class members itself. This means you can end up with a lot of redundant (in other words, hard to maintain) initialization code or else create yet another function to do the common elements. Through delegation, C++0x will allow constructors to call other peer constructors. Other languages, such as Java, already provide this. For example,

class SomeType
{
   int number;

public:
   SomeType(int newNumber) : number(newNumber) {}
   SomeType() : SomeType(42) {}
};

In this example, the default constructor calls the peer constructor SomeType::SomeType(int) with the value 42. There’s more to consider with respect to the fact that C++00X considers the object “constructed” after the first constructor has been called. For details, see N1986.

Static Asserts

In today’s C++, neither the assert() macro nor #error can be used with templates. Because template instantiation doesn’t happen until after preprocessing, the #error is useless for templates. Similarly, the assert() macro is a runtime catcher and does not help catch issues that should be addressed at compile time. With C++0X, the static_assert allows simple and uniform compile time checking for a variety of scenarios. The usage is:

static_assert( constant-expression, error-message ) ;

You can use static_assert() in relatively simple checks:

static_assert( PI < 3.14 || PI > 3.15, " PI is inaccurate!" ) ;

Or, inside a template to do some type validations.

template< class T >
struct Check
{
   static_assert( sizeof(int) <= sizeof(T), "T is not big enough!" ) ;
} ;

For more info, consult N1720.

Template Aliasing

You can use template aliasing today only if you happen to have the complete parameter list defined by a typedef. Because you can’t create an alias with undefined parameters per se, a lot of code that uses STL looks harder to read (and write) than it really should. You can work around this issue today mostly by clever use of default parameters or by encapsulating it through yet another template. In C++00X, you will first declare the aliasing just ONCE with the “using” keyword:

template< class T > using Vector = MyVector< T, MyAlloc<T> > ;

Then, when it comes time to actually instantiate a variable, you can use the much easier to understand:

Vector<int> int_vector ;

Instead of the usual gobbledy-gook:

MyVector<int, MyAlloc<int> > int_vector ;

Variadic Templates

In C and C++, there is always a fixed number of arguments that a function can take and these arguments have defined types. The exception is, of course, the odious printf() family of functions that use the old “varargs” method of argument passing. Variadic templates get around this problem by allowing a function to take an arbitrary number of arguments. A full discussion of variadic templates is outside the scope of what I can cover in this article, although others have done so.

Extern Templates

Every module that instantiates a template essentially creates a copy of it in the object code. Then, it’s up to the linker to dispose of all of the redundant object code at the very last stage, thus slowing the critical edit-compile-link cycle that makes up a programmer’s day (or sometimes daydreams). To short-circuit this object code garbage collection, a number of compiler vendors have already implemented an extern keyword that can go in front of templates. This is a case of standardization codifying existing industry practice (pun intended). In practice, this is implemented by sending a notice to the compiler basically to “not instantiate this here”:

extern template class std::vector<MyClass>;

Strongly Typed Enums

Although all of us have been trained that enums are vastly superior to their predecessors (the ubiquitous #define), there are still a lot of shortcomings in everyday usage. In some sense, you get the worst of both worlds: Enums are not integers nor are they completely typesafe. The only practical protection you have is that you can’t directly substitute one enum type for another, although any fool can cast it to an int. More insidious is that you have no control over the implementation of the enum type; it’s generally as big as an int but your mileage may vary. Last, is the continual annoyance that two different enumerations in the same scope can’t have any overlapping enum tokens in common. This rules out using intuitive names like “OK”, “ERROR”, and so on because there is always a risk it will collide with somebody’s third-party library. C++0X solves all these issues neatly by creating a class-based enum whose base-type is well-defined, scope resolvable, and can never be cast away to an int. For example:

enum class Status : unsigned long
{
   GOOD,
   BAD,
   WARNING = 100    // etc.
};

See N2347 for specifics.

What’s Not Going in Yet

A language is not only defined by what goes in but also but what’s not there whether by design or by default. In any standards update, probably a lot more goes overboard than goes into the final standard. Still, it provides valuable insights into the minds of the designers to know what didn’t pass muster.

Because most computers shipped in 2008 will have at least two CPU “cores,” the issue of how to put multithreading into the C++ standard has a lot of interest. You may be familiar, for example, with the Posix pThreads library, which is one such independent solution for C functions. A complete multithreading solution would have to account for many aspects of thread management including: parallel execution, asynchronous function calls, thread-local storage, atomic operations, and extending the use of the “volatile” keyword.

Currently, when a derived class is created from a base class, the derived class has an entirely separate set of constructors. The derived class may call base class constructors and forward parameters to them, but it’s still up to the developer to create each constructor separately. As with life before delegating constructors, it doesn’t require much thought and encourages cut-and-paste errors. This could be solved by inheriting constructors, although it is currently “under review” and not yet in the “working document” (see N2376).

What’s More…?

In the space of this article, I’ve been able to touch only a few of the cutting edge aspects of C++0X. It is my hope that you’ve got some idea of what’s ahead in these areas and how your libraries and apps could benefit from the new possible constructs. Stay tuned to this channel and I’ll be providing more information in the weeks and months to come leading up to eventual ISO ratification in 2009.

About the Author

Victor Volkman has been writing for C/C++ Users Journal and other programming journals since the late 1980s. He is a graduate of Michigan Tech and a faculty advisor board member for Washtenaw Community College CIS department. Volkman is the editor of numerous books, including C/C++ Treasure Chest and is the owner of Loving Healing Press. He can help you in your quest for open source tools and libraries, just drop an e-mail to sysop@HAL9K.com.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories