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:


         void foo(vector<MySpace::MyClass *> x)


            for (auto ptr = x.begin(); ptr != x.end(); ptr++)


               ...  // Code modifying the data




Without auto, the type for variable ptr would be  vector<MySpace::MyClass *>::iterator.  Moreover, any change to this container, such as changing it from a vector<> to a list<>, or changing the class name or namespace, would require changes in the ptr variable definition, despite the fact its type is completely unnecessary to note (other than for the compiler).


Note that an initializer is still required to use auto for C++0x:


         auto   x; // still illegal in C++0x


But suppose you knew what type you wanted (based upon another variable) but did not want to initialize?  The new decltype keyword is available for just such purposes, as the following example shows:


         bool SelectionSort(double data[256], double tolerance);

         bool BubbleSort(double data[256], double tolerance);

         bool QuikSort(double data[256], double tolerance);

         decltype(SelectionSort)  mySortFcn;

         if (bUseSelectionSort)   mySortFcn = SelectionSort;

         else if (bUseBubbleSort) mySortFcn = BubbleSort;

         else                     mySortFcn = QuikSort;


With the inclusion of auto & decltype in C++0x, a great deal of simplicity is restored to C++ development, without any loss of power. 


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: