Ruminations on C++11

///////////////////////////////////////////////////////////////////////////
// Preface
//////////
//
// This is a blog about the new version of C++, C++11. It has been many years in the
// making and adds lots of new features to the C++ language. Some of those features
// are already supported by commonly used compilers, a description of these features
// follows.
//
// As you can see, this 'blog' is a bit unusual. It's actually a C++ source code file
// annotated with lots of comments. So it can be read on its own, with the code being
// examples of the things being described, or it can be viewed in Visual Studio (VS)
// 2010, built and even executed. With a few minor adjustments pointed out along the
// way, it can also be built using GCC and executed on whatever system that it is
// installed on.


/////////////////////////////////////////////////////////////////////////////////////////
// Ignore these, I couldn't think of anywhere else to put them.
#include "stdafx.h"
#include <vector>
#include <algorithm>
#include <map>
#include <iostream>
/////////////////////////////////////////////////////////////////////////////////////////
// Ruminations on C++11 (the bits currently supported anyway).
//////////////////////////////////////////////////////////////
//
// Of the many new features of C++11, only a subset are available on stable releases of
// the well-used contemporary C++ compilers. I thought that it would be a good exercise
// in understanding these new features to try them out. I decided that I'd try VS2010 on
// Windows 7 and GCC on Ubuntu, as these are easy for me to access and a reasonable
// approximation of other developers environments.
//
// The main differences being there is no support for nullptr in GCC, and no support for
// initialiser lists in VS2010. Of these, the initialiser lists seem the most useful feature, I hope it gets into VS soon.
//
// The features described here are:
//     * static_assert
//     * trailing return types
//     * constructors calling other constructors in the same class
//     * lambda functions
//     * initialiser lists
//     * a fix for the 'std::map< int, std::vector<int>>' '>>' problem
//     * 'auto' variable declarations
//     * 'decltype' variable declarations
//     * rvalue references, move constructors and perfect forwarding
//     * nullptr, improved typing for the null pointer value
//
// I have annotated some C++11 code that shows the new features, this code does not fully
// comply with our coding standards in order for the descriptions to be clearer. This
// blog contains code that compiles with VS2010, the GCC supported C++11 features are
// provided in the comments.
// 1. static_assert
///////////////////
//
// First we have an example of 'static_assert', these are compile time assertions. In
// this case, a check is made to ensure that the size of the type used to instantiate the
// object is sufficient. This check occurs at compile time, so the supplied error message
// is displayed as a compile error if the condition is false.
//
template<class T>
class TemplateTest
{
    // if the size of the type used to instantiate an object is too small, a compile
    // time error is produced.
   static_assert( sizeof(T) > 1, "sizeof(T) not > 1!" );
   T m_test;
};
// 2. Trailing return type declarations
///////////////////////////////////////
//
// Next up, an example of trailing return types on method declarations.
// If we have a class that defines an enumeration (very handy for code clarity).
class MyEnumClass
{
public:
    enum MyHelpfulEnum
    {
        An,
        Enumeration,
        That,
        Usually,
        Helps,
        To,
        Clarify,
        Code
    };
    MyEnumClass();
    MyEnumClass( MyHelpfulEnum initialValue );
    // We can declare the method like this, with a trailing return type,
    static auto KeepCodeClear() -> MyHelpfulEnum;
    // or like this, it makes no difference to the compiler.
    //static MyHelpfulEnum KeepCodeClear();
    // But I think it is helpful to keep things consistent.
};
// The advantage of this feature comes when declaring the method implementation, as this
// method returns an enumeration defined within the class. Previously you'd have to
// declare the method decorated with lots of scope to help the compiler know what was
// going on (it has enough to contend with without having to deal with this kind of
// thing). Like so,
//
//MyEnumClass::MyHelpfulEnum MyEnumClass::KeepCodeClear()
//
// But now you can declare the method like this.
auto MyEnumClass::KeepCodeClear() -> MyHelpfulEnum
// The '->' is a little different, but less repetition is involved (sort of).
{
    // we'll see more from 'auto' later (why keep a keyword for one use when it can
    // have three!?)
    return Usually;
}
// 3. One constructor calling another
/////////////////////////////////////
//
// Here we have an example of one constructor calling another, I found it annoying that
// this was missing from C++ in the past.
MyEnumClass::MyEnumClass()
{
    // this constructor can call another constructor.
    MyEnumClass( Helps );
}
MyEnumClass::MyEnumClass( MyHelpfulEnum initialValue )
{
}
// Here are some function prototypes for the nullptr description (something to look
// forward to).
void NullPointerCall( int notAPointerParameter );
void NullPointerCall( int* aPointerParameter );
// 4. Lambda functions
//////////////////////
//
int _tmain(int argc, _TCHAR* argv

[])

{
    // Next we have an example of a lambda function (familiar to C# developers). I
    // have to admit I'm not a fan of these; if it's a function make it one, at least
    // it can be called from other places then. Now I've got that rant out of the way
    // we can continue!
    //
    // If we have a list of interest:
    std::vector<int> anInterestingList;
    // And that list has some elements, in GCC we can use initialiser lists, like
    // so...
    //std::vector<int> anInterestingList{1,2,3,4}; // so much nicer.
    //
    // But for VS we cannot, so add some elements the old fashioned way.
    anInterestingList.push_back( 1 );
    anInterestingList.push_back( 2 ); // boo
    anInterestingList.push_back( 3 );
    anInterestingList.push_back( 4 ); // hiss
    // Declare an accumulator for our demonstration.
    int accumulator( 0 );
    // From time to time, it is necessary to loop through all the elements in a list
    // (not all that often, but it does happen).
    std::for_each( anInterestingList.begin(), anInterestingList.end(),
    // Below is the lambda function, the start is defined by '[', the ampersand
    // defines the capture list (the variables accessible by the lambda function),
    // if the capture list is empty, i.e. there is only '&', all variables in scope
    // are available. It seems like good practice to explicitly state what is
    // accessible rather than implying everything. If no '&' appears, i.e '[]' is
    // used, no variables are captured. There is also, like any other function a
    // parameter list.
                   [&accumulator](int element){ accumulator += element; } );
                   // the lambda function, accumulates the values in the list.
    std::cout << "Accumulator = " << accumulator << std::endl;
    // 5. '>>' in variable declarations
    ///////////////////////////////////
    //
    // The next feature is more of a fix than anything else. Allowing '>>' in
    // declarations. Of course you could always get around this problem by sub
    // classing, (or even using typedef, but that's not very OO is it?) but if you did
    // do this the error message was, well, ...confusing (I'll leave it at that before
    // I say something I shouldn't).
    std::map< int, std::vector<int>> lookItWorks;
    // It's better to subclass if you can though. This is not a C++11 feature, but I
    // rarely see it in C++ and it seems so obviously OO.
    class AListOfInts : public std::vector<int>{};
    class AMapOfIntvsInts : public std::map< int, AListOfInts>{};
    // Of course if you wish to use the constructors of the base classes this method
    // is annoying. If only there was a way...
    AMapOfIntvsInts anAsideToProceedings;
    // Well C++11 allows the use of 'using' to use base class constructors in derived
    // classes, which helps this 'problem'. If they were implemented by VS or GCC
    // I'd add an example.
    // 6. 'auto' types for variable declarations
    ////////////////////////////////////////////
    //
    // This very simple extract of code shows another new use of the auto keyword.
    // Here you let the compiler automatically deduce the type.
    auto autotest( anInterestingList.begin() );
    // 7. 'decltype' types for variable declarations
    ////////////////////////////////////////////////
    //
    // Similar to the 'auto' type deduction feature above, this time declaring a type
    // that is the same as another type.
    decltype(autotest) decltypetest(autotest);
    // declare decltypetest as the same type as autotest.
    std::cout << "*autotest = " << *autotest << std::endl;
    std::cout << "*decltypetest = " << *decltypetest << std::endl;
    // 8. rvalue references
    ///////////////////////
    //
    // As you can only assign lvalues (like variables, objects and other references)
    // to references, C++11 introduces rvalue references for the others (like
    // temporaries and literals). I'm not going to get into the details here as
    // those subjects require whole documents to themselves. So you can have:
    int aValue( 9 );
    int& myPreferenceIsAReference( aValue );
    int& alsoReferingToAValue( myPreferenceIsAReference );
    // But you can't have:
    // MyEnumClass::MyHelpfulEnum& isTheCodeClear( MyEnumClass::KeepCodeClear() );
    // as the return from MyEnumClass::KeepCodeClear() is a temporary variable.
    //
    // In C++11 using rvalue references you can:
    MyEnumClass::MyHelpfulEnum&& isTheCodeClear( MyEnumClass::KeepCodeClear() );
    if ( isTheCodeClear == MyEnumClass::Usually )
    {
        std::cout << "isTheCodeClear == MyEnumClass::Usually, must do better!"
                  << std::endl;
    }
    // You can also do things that seem very strange.
    int&& rValueRef = 2;
    // assign the rvalue reference to a reference to an rvalue, in this case the
    // literal number 2.
    ++rValueRef;
    // Has this blown your mind? We have incremented 2! Surely all that we know and
    // love is doomed. It's ok though, as rValueRef is assigned a reference to a
    // temporary variable, this is saving time rather than creating a temporary
    // and then copying it to a variable.
    std::cout << "rValueRef referencing the literal number 2 = "
              << rValueRef << " OMG!" << std::endl;
    // These two examples show that less copying of values is attained by using rvalue
    // references. The C++11 standard libraries and STL have been written to take
    // advantage of this to improve performance without requiring users of these
    // libraries to do anything different (apparently). There's lots of talk about
    // 'move semantics' and 'perfect forwarding' which is nice if you like that kind
    // of thing, these subjects require blogs of their own.
    // In summary, they allow less copying, making copy constructors and equals
    // operators more efficient. This in turn helps developers to write logical
    // code that is far less likely to cause performance issues.
    // 1. (again) static_assert
    ///////////////////////////
    //
    // static_assert (for compile time assertions). This time we are using the
    // static_assert feature to check the sanity of a constant value against another
    // constant. This is especially useful to stop people changing constants to
    // erroneous values.
    const int someConfigValue = 1;
    const int someConfigValueCheck = 2;
    // As before in the template example, if the condition is false the compiler
    // outputs the error text supplied.
    static_assert( someConfigValue < someConfigValueCheck,
                   "someConfigValue is not less than someConfigValueCheck!" );
    TemplateTest<int> inttest;
    // This is fine, an int passes the static_cast in TemplateTest.
    // TemplateTest<bool> booltest;
    // This generates a compile time error due to the static cast in the template
    // class defined above.
    // 9. nullptr
    /////////////
    //
    // nullptr is more strongly typed than 0 or NULL, which helps make things clearer.
    // nullptr is not available on GCC at the time of writing so comment out the rest
    // of this example to compile with GCC.
    int* nullptrtest( nullptr );
    if ( nullptrtest == nullptr )
    {
        // the pointer is null.
        std::cout << "The nullptrtest null pointer is set to nullptr."
                  << std::endl;
    }
    // If we don't use nullptr, which function is called for our old null pointer
    // values?
    NullPointerCall( 0 );
    NullPointerCall( NULL );
    // If we use nullptr instead things are clearer.
    NullPointerCall( nullptr );
    // 10. initialiser lists
    ////////////////////////
    //
    // This is supported by GCC, but not VS, so I've commented it out. Obviously
    // initialiser lists can also be used to pass data to methods. I think this is one
    // of the more useful features of C++11, if only for reasons of clarity.
    //std::map< int, int> myuselessnumbermap{ { 1,1 }, { 2, 2 } };
    // There are many other C++11 features that haven't made it into stable versions
    // of either VS or GCC, but now that the standard has been ratified I expect they
    // will soon follow. Better enum support, in-class member variable initialisation,
    // override control and thread support like thread local storage are all useful
    // features, there are many more new features that future compilers will support.
    // See http://www2.research.att.com/~bs/C++0xFAQ.html for a description of these
    // and the unimplemented C++11 features (aka C++0x, they must've been a bit late).
    return 0;
    // Literals in code!! Just this one time I'll let myself off (anyway, I've broken
    // most of our other coding standards along the way).
}
// These are the implementations of the nullptr description function calls.
void NullPointerCall( int notAPointerParameter )
{
    std::cout << "So you'd like me to process your integer?" << std::endl;
}
void NullPointerCall( int* aPointerParameter )
{
    std::cout << "So you'd like me to process your pointer?" << std::endl;
}