Mirror of MacCompanion

macCompanion magazine






About Us








"Foreign" Macs



Link Lists

Mac 3D


Mac Jobs

MUG Shots




Think Different



Download this issue

According to Hoyle

According to Hoyle...

C++0x Part 3: Making Coding Easier



December 2009

by Jonathan Hoyle


Two months ago, we began our series on the changes that will be coming the C++ language.  Last month we examined some of the updates which were expected to take place: fixing embarrassments and syncing up with ANSI C99 changes.  With this month, we look at some more improvements available to C++ developers of the future.  Specifically, changes which make coding easier.



Standard C++ Library Enhancements

The Standard C++ Library, including STL (the Standard Template Library), is a generous supply of useful containers and utilities. Despite its fullness of capabilities, there were still a number of components missing.  C++0x fills these gaps:

regexA long awaited regular expressions class

    array<>: A one-dimensional array containing its size (can be 0)

    STL hash classes: unordered_set<>, unordered_map<>, etc.

    tuple<>: A templated tuple class, eg: tuple<int,void *,double>

Mac users are fortunate in that they do not have to wait for the Standard Library changes: they are available today in gcc 4 (the compiler inside Xcode 2.x and later).  These library additions are within the library namespace std::tr1:: ("tr1" stands for Technical Report #1, the standard's committee report defining these new classes).




Variadic Templates

For years, the C language has allowed functions to have a variable number of parameters.  Unfortunately, this was not true of template arguments within C++98.  In C++0x, templates can have a variable number of types.  Here is an example in which a templated DebugMessage() function can take advantage of variadic templates:

    // Prints to stderr only when DEBUG flag set
    template <typename... TypeArgs>
    void DebugMessage(TypeArgs... args)


        #ifdef DEBUG
... // Implement writing to stderr

    // Do nothing



    // Later in code
DebugMessage("The value of n = ", n)

    DebugMessage("x = ", x, ", y = ", y, ", z = ", z)


                                  " time = ", clock(),

                                  ", filename = "__FILE__,

                                  ", line number = "LINE__,

                                  ", inside function = ", __func__);

This new flexibility with macros will make it easier for developers wishing to use them, as their current restrictions make them occasionally cumbersome.




Delegating Constructors

Other languages, such as C#, allow one class constructor to invoke another.  In C++98, this was not possible, thus requiring the class designer to create a separate initialization function if it wished to use common code across multiple constructors.  In C++0x, this becomes available, as the following example shows:

    class X
            X();           // default constructor
            X(void *ptr);  // takes a pointer
            X(int value);  // takes an int

    X::X(): X(NULL// calls X(void *)
        ...  // other code

    X::X(void *ptr): X(0// calls X(int)
        ...  // other code

    X::X(int value) // does not delegate
        ...  // other code

With constructor delegation, C++ class designers can simplify their implementations.




NULL Pointers

In ANSI C, NULL is defined as (void *) 0.  In C++, the use of NULL is deprecated.  Why?  Because unlike in C, it is illegal in C++ to directly assign a void pointer to any other type of pointer (without a cast):

    void  *vPtr = NULL;   // legal C, legal C++
int   *iPtr = NULL;   // legal C, illegal C++
                          // Cannot assign void * to int * in C++
    int   *iPtr = 0;      // legal C++

However, the proliferation of NULL in C++ code remains so great, many compilers simply generate a warning, not an error, when such a pointer assignment mismatch takes place.  Others redefine NULL in C++ as simply 0.  Despite these occasional compiler courtesies, it is still very confusing for beginning C++ programmers, especially in examples such as these:

    void foo(int);       // takes an int
void foo(char *);    // takes a char ptr
    foo(0);              // Is this "0" to be a ptr or a number?
    foo(NULL);           // No matching prototype (no void *)

For this reason, C++0x introduces nullptr, a type-safe nil pointer which can be used with any pointer, but is not compatible with any integral type:

    char *cPtr1 = nullptr;    // a null C++ pointer
    char *cPtr2 = 0;          // legal, but deprecated
    int nnullptr;          // illegal
    X *xPtrnullptr;        // can be used with any ptr type
    void foo(int);            // takes an int
void foo(char *);         // takes a char ptr
    foo(0);                   // calls foo(int)
    foo(nullptr);             // calls foo(char *)

Essentially, C++ programmers now have a type-safe replacement for NULL, which matches similar behavior in other more recent languages.




The Amazing Return of auto

When the C language first evolved, the auto keyword was used to specify to the compiler that a variable was being allocated on the stack, for example:

    auto     x;     /* implicitly an int, placed on stack */

Then ANSI C was ratified in 1989, the implicit int rule was removed:

    auto     x;     /* now illegal in ANSI C */
    int      x;     /* OK, auto assumed */
    auto int x;     /* OK, but redundant */

Since that time, auto remained a keyword in the C (and later C++) languages, even though virtually no one had used it since the 1970's.  After over 30 years of disuse, the C++0x standard will reintroduce the auto keyword to mean that the variable type is implied by the initializer:

    auto       x = 10;     // x is an int
    auto       y = 10.0;   // y is an double
    auto       z = 10LL;   // z is a long long
    const auto *p = &y;    // p is a const double *

The savings becomes more significant with complicated types, such as the following example:

    void *foo(const int doubleArray[64][16]);

    auto       myFcnPtr = foo;
               // myFcnPtr is of type "void *(const int(*)[16])"

In addition, auto becomes useful for temporary variables whose types aren't important but merely just have to match.  Consider the following function which walks through an STL container:

Coming Up: 

C++0x Part 4: Smart Pointers

C++0x Part 5: Rvalue References

C++0x Part 6: Final Thoughts


To see a list of all the According to Hoyle columns, visit: