C++11

Inhalt

References:
  • Nicolai Josuttis,
    The C++ Standard Library,
    A Tutorial and Reference,
    Addison-Wesley, 2012
  • Rainer Grimm,
    C++,
    Der Leitfaden für Programmierer zum neuen Standard,
    Addison-Wesley, 2012

This text also contains own comments and examples

Compiler support for C++11
apache.org
Microsoft Visual Studio
Online compilers to test code snippets
Coliru
Ideone

Top1 Core language

Top1.1 Template brackets without spaces: >>

It is no longer necessary to add blanks between template brackets:
std::vector<std::list<int>> myContainer;
C++11 will recognize the difference to iostream operator ">>".

Top1.2 Raw string literals

Especially when having to use special characters within a string constant there is a comfortable way to directly define the string as a raw string literal:
//old fashioned way using escape sequences:
std::string filePathOld= "C:UserDataGeraldSW";

// use a raw string literal
std::string filePathNew = R"(C:UserDataGeraldSW)";
Raw string literals are more readable than the escaped strings.

Recommendation:
Always use raw string literals when defining complex expressions containing backslash characters (e.g. as used within regular expressions).

Top1.3 Typesafe null pointer: nullptr

// Initialize a pointer
SomeClass* pSomeClass = nullptr;
  • Depending on their specific definition old constant values "0" or "NULL" may be treated as int.

    Example:

    • Assume SomeFunc(void*) and SomeFunc(int) are available
    • Calling SomeFunc(NULL/0) may resolve to SomeFunc(int) which probably is not what you need.
    • SomeFunc(NULL) may be ambiguous and cause a compile error
  • the new constant "nullptr" has type std::null_ptr_t and no longer resolves to int type
  • nullptr supports forwarding via template function,
    for more details see nullptr - usage info at CppReference.com

Rule:
Always use "nullptr" when needing a pointer to nothing.
Do not use old fashioned constants "0" or "NULL"!

Top1.4 Typesafe scoped enumerations: enum class

  • Define scoped enum (with default type int):
    enum class Color
    {
        RED,
        GREEN,
        BLUE
    };
    
  • To access an enum value the class scope has to be used
    Color color = Color::GREEN;
    
  • To reduce dependencies forward declarations are possible:
    enum class Color;
    
  • Enum values are not implicitly converted to/from int. But explicit conversions are possible:
    Color color = static_cast<Color>(2);          // -> BLUE
    int val     = static_cast<int>(Color::GREEN); // -> 1
    
  • You can explicitly define the integral type (e.g. char, unsigned short, long, ...) used for storing the enum:
    // Definition
    enum class Color : char {RED, GREEN, BLUE};
    
    // The type has to be used also within forward declaration:
    enum class : char;
    
  • Analogous to regular enums you can assign explicit values to your scoped enum:
    enum class Color
    {
        RED,       // -> value 0
        GREEN = 7, // -> value 7
        BLUE       // -> value 8
    };
    

Recommendation:
As old fashioned enum constants pollute the global namespace always prefer using scoped enumerations!
Alternatively think about embedding old fashioned enums within specific namespaces (e.g. when your compiler does not yet support C++11).

Top1.5 Range based for loop

std::vector<int> container;

// Define element with reference type to be able
// to perform changes
for (int & element : container)
{
    element += 4;
}

Top1.6 Automatic type inference - auto

// assume there is a map containing for each
// custumer id an according custumer name
typedef std::map<int, std::string> Customers;

void WriteCustomers(Customers const & in_customers)
{
    for (auto customer: in_customers)
    {
        std::cout << customer.second << std::endl;
    }
}
The usage of auto releases you from using complexer code like
    for (std::map<int,std::string>::value_type customer : in_customers)
    {
       std::cout << customer.second << std::endl;
    }

    // With use of typedef Customers the complex type could
    // also be simplified to Customers::value_type
Warning
It is possible to excessively use "auto" nearly everywhere. The compiler will easily replace each definition with the correct type matching in each context. As a result the writing of code is simplified.

Assuming you are not working on a trivial or prototype project (a "write once-change never" project), then probably you are forced to work with your code a couple of years. A single line of code is written once but perhaps you (or someone having to extend your code) has to read it multiple times during the development cycle. Is the reader as quick as the compiler to automatically assign the proper type information to 10 different auto variables used within a function?

Recommendation:
Use "auto" with care. Restrict the usage mainly to cases where complex type definitions can be simplified (e.g. when using iterators, functions or lamdas). The reader of your code will thank you (in many cases this person is you, a couple of months later)!

Top1.7 Assertions at compile time and type traits

The well known "assert()" allows a verification of conditions at runtime. With use of the new "static_assert" you can instruct the compiler to give you specific hints when some assumptions concerning compile time conditions are no longer fulfilled.

Top1.7.1 Checking simple conditions at compile time

// Assumption: you are needing a number of bits
// and you want to use a basic integral type as storage
const int NUM_USED_BITS = 18; // value may change during development
typedef short int MyBitfieldType;

// Check at compile time whether your bits
// can be stored within your desired type
static_assert(sizeof(MyBitfieldType)*8 >= NUM_USED_BITS,
    "MyBitfieldType cannot store all used bits,
     please choose bigger integral type");
Usually a short int consists of 2 bytes and is able to store only 16 bits. Therefore the static_assert will generate the following compile error:
MySourceFile.cpp(670): error C2338: MyBitfieldType cannot store
    all used bits, please choose bigger integral type

Top1.7.2 Type traits library

The type traits library enables you to check various type and class properties.
Some specific class types and a check function
class MyBaseClass
{
public:
	virtual ~MyBaseClass() {}
	virtual void SomeBaseMethod() = 0;
};

class MyDerivedClass : public MyBaseClass
{
	void SomeBaseMethod() override {};
};

// Macro to simplify writing
#define CHECK_PROPERTY(EXPRESSION,TYPE) 
    std::cout << #EXPRESSION "=" << std::EXPRESSION<TYPE>::value 
              << std::endl;

template <typename T>
void CheckType()
{
	std::cout << "nChecking type " <<
		typeid(T).name() << std::endl; // RTTI info

	std::cout << "is_pod=" << std::is_pod<T>::value << std::endl;
        // with support of a macro less verbous:
	CHECK_PROPERTY(is_integral,T);
	CHECK_PROPERTY(is_class,T);
	CHECK_PROPERTY(is_function,T);
	CHECK_PROPERTY(is_abstract,T);
	CHECK_PROPERTY(is_polymorphic,T);
	CHECK_PROPERTY(has_virtual_destructor,T);
}
Using given types and check functions at runtime
int i = 14;
MyDerivedClass derived;
CheckType<int>();
CheckType<MyBaseClass>();
CheckType<MyDerivedClass>();
Output:
Checking type int
is_pod=true
is_integral=true
is_class=false
is_function=false
is_abstract=false
is_polymorphic=false
has_virtual_destructor=false

Checking type class MyBaseClass
is_pod=false
is_integral=false
is_class=true
is_function=false
is_abstract=true
is_polymorphic=true
has_virtual_destructor=true

Checking type class MyDerivedClass
is_pod=false
is_integral=false
is_class=true
is_function=false
is_abstract=false
is_polymorphic=true
has_virtual_destructor=true

Top1.7.3 Checking complex type and class conditions at compile time

You can instruct the compiler to check some expected conditions within your generic (template) code:
01 // MySourceFile.cpp
02
03 template <typename T>
04 void DoSomethingWithIntegral(T t)
05 {
06    static_assert(std::is_integral<T>::value,
          "please use an integral type");
07    static_assert(!std::is_class<T>::value,
          "class type is not allowed here");

    // do something useful
08 }
09
10 template <typename T>
11 void DoSomethingWithClass(T t)
12 {
13    static_assert(std::is_fundamental<T>::value == false,
          "fundamental type is not allowed here");
14    static_assert(std::is_class<T>::value == true,
          "please use a class type");

    // do something useful
15 }
when compiling the following code:
39 ...
40 int i = 14;
41 MyDerivedClass derived;
42
43 DoSomethingWithIntegral(i);
44 DoSomethingWithIntegral(derived);
45
46 DoSomethingWithClass(i);
47 DoSomethingWithClass(derived);
you will get the following compiler output:
MySourceFile.cpp
c:MySourceFile.cpp(06): error C2338: please use an integral type
    c:MySourceFile.cpp(44) : see reference to function template
      instantiation 'void DoSomethingWithIntegral(T)' being compiled
    with
    [
        T=MyDerivedClass
    ]
c:MySourceFile.cpp(07): error C2338: class type is not allowed here
c:MySourceFile.cpp(13): error C2338: fundamental type is not allowed here
    c:MySourceFile.cpp(46) : see reference to function template
      instantiation 'void DoSomethingWithClass(T)' being compiled
    with
    [
        T=int
    ]
c:MySourceFile.cpp(14): error C2338: please use a class type
References: type traits, static_assert

Top1.8 Reference wrapper (std::ref, std::reference_wrapper)

References differ from regular values in certain ways. By wrapping them into class std::reference_wrapper<YourType> you can make them copy constructable and copy assignable. This allows to do the following things which are not possible for regular references:
  • store them within STL containers
  • copy a class instance containing a reference
When using std::bind and std::function (see next section) it is often necessary to pass a function argument as reference or const reference. For this purpose you can use the functions std::ref and std::cref which will return an appropriate std::reference_wrapper type for your argument.

Example for storing references within a STL container
Assume you have some struct:
struct Info
{
    Info (std::string const & in_description, long in_value)
        : m_description (in_description)
        , m_value (in_value)
    {}

    std::string m_description;
    long        m_value;
};
Then you can store references to it within a std::vector:
Info infoA ("Some Info A", 314);
Info infoB ("Some Info B", 4711);
	
// does not compile
// std::vector<Info&> vRef;

// wrapping reference works
std::vector<std::reference_wrapper<Info>> vRef;

// adding references to container
vRef.push_back (std::ref(infoA));
vRef.push_back (infoB); // std::ref can be omitted

// change infoA through reference (available through get())
vRef[0].get().m_description = "changed description";

//change through original instance
infoA.m_value++;

// proof that there is only one object instance
assert (infoA.m_description == vRef[0].get().m_description);
assert (infoA.m_value       == vRef[0].get().m_value);
assert (infoA.m_description == "changed description");
assert (infoA.m_value       == 315);
Usage info at CppReference.com:
std::ref, std::cref
std::reference_wrapper

Top1.9 bind and function

Usage info at CppReference.com:
std::bind
std::function

Top1.9.1 Basic functionality

Using std::bind you can partly evaluate an existing function. The result is a callable new function which can be stored within an instance of std::function. The std::function object can be transferred like regular data.

With std::bind you can

  • change the order of function arguments
  • reduce the number of required arguments by setting some presets for not variable arguments

Example
Assume you have a function expecting some kind of result information:
bool SetResult (int in_resultCode, std::string const & in_context)
{
    std::cout << "SetResult result=" << in_resultCode
              << " context=" << in_context
              << std::endl;
    return true;
}
Then you can bind this function to a changed signature:
// allow simple use of placeholders _1, _2, ...
using namespace std::placeholders;

// Define your function signature
typedef std::function<bool(std::string const &, int)> MyResultFunc;

// Bind the existing function to the new signature
// and store the result in a std::function
// (in this example the paramter order is reversed)
MyResultFunc resultFunc = std::bind(SetResult, _2, _1);

// call the stored function
resultFunc ("only for test", 17);
Output:
SetResult result=17 context=only for test

Top1.9.2 Binding to class member functions

You can bind a call to a member function of a specific class instance to a regular std::function. Possible motivation: the client code using the std::function does not need to know the called object.
Example
Assume you have an callback object waiting for some result from client code:
class MyCallbackObject
{
public:
    ~MyCallbackObject()
    {
        std::cout << "Destructor MyCallbackObject" << std::endl;
    }

    bool ReceiveResult (int in_resultCode, std::string const & in_context)
    {
        std::cout << "MyCallbackObject: result=" << in_resultCode
                  << " context=" << in_context
                  << std::endl;
        return true;
        // may return false e.g. to signal that the
        // result is no longer processed
    }
};
Then you can bind to member function ReceiveResult:
    typedef std::function<bool(int)> MyCallbackFunc;

    MyCallbackObject cbo;

    // Using pointer to object to avoid creating temporary instances of cbo
    MyCallbackFunc cbFunc = std::bind(
        &MyCallbackObject::ReceiveResult, &cbo, // member function + object
        _1,                                     // parameter
        "not set");                             // preset for param

    // Simple syntax also works, but creates two temporary
    // instances of MyCallbackObject
    // MyCallbackFunc cbFunc2 = std::bind(
    //    &MyCallbackObject::ReceiveResult, cbo,
    //    _1, "not set");

    // Reference to object also avoids creating temporary
    // instances of cbo
    // MyCallbackFunc cbFunc2 = std::bind(
    //     &MyCallbackObject::ReceiveResult, std::ref(cbo),
    //     _1, "not set");

    ...
 
    // Finally call the stored member function
    cbFunc(42);
   }
Output:
MyCallbackObject: result=42 context=not set

Top1.9.3 Hiding a refcounted object within a std::function

When working with refcounted objects (e.g. within multithreaded environments) a callback to some class instance can only be performed savely if the calling client code also owns a valid reference to the object (e.g. by storing a refcounted smartpointer to the object).

To make client code independent from those details you can hide the object and the reference counting within the stored std::function. From the client's point of view he simply calls a function and need not to bother about obejct validity and lifetime.

Example
Assume you have the same class MyCallbackObject as in the last section. Only extended by a shared pointer type:
#include <memory> // shared_ptr

class MyCallbackObject
{
    ...
};
typedef std::shared_ptr<MyCallbackObject>MyCallbackObjectSp;
You can encapsulate the creation of the std::function containing a refcounted object:
MyCallbackFunc CreateCallbackFunc()
{
    std::cout << "CreateCallbackFunc: Begin" << std::endl;

    // Create a callback object to receive some callback later in time
    MyCallbackObjectSp spCbo = std::make_shared<MyCallbackObject>();

    // Pack a shared pointer to the callback object within the
    // std::function to keep the object alive
    MyCallbackFunc cbFunc = std::bind(
        &MyCallbackObject::ReceiveResult, spCbo, // member func, smart pointer
        _1, "not set");

    std::cout << "CreateCallbackFunc: End" << std::endl;

    return cbFunc;
    // here the shared pointer spCbo goes out of scope
    // the only reference to the callback object
    // is contained within the std::function
}
Assume you have some client code function which finally calls back:
void DoSomethingAndSendResultViaCallback (MyCallbackFunc in_callbackFunc)
{
    // do something
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    // here nothing is visible about object and refcounting
    in_callbackFunc(89);
}
Concrete scenario using the code snippets from above:
MyCallbackFunc cbFunc = CreateCallbackFunc();

// Pass callback to asynchronoously
// executed function
// (in real code it may be the cient code
// deciding to use a separate thread)
std::thread t (DoSomethingAndSendResultViaCallback, cbFunc);

cbFunc = MyCallbackFunc(); // release stored refcount
std::cout << "local function object is reset without calling it" << std::endl;

// Synchronize with thread execution
t.join();
std::cout << "thread is joined" << std::endl;
Output:
CreateCallbackFunc: Begin
CreateCallbackFunc: End
local function object is reset without calling it
MyCallbackObject: result=89 context=not set  // called from client thread
Destructor MyCallbackObject                  // called from client thread
thread is joined
Responsibility of the client - release of resources
When a client no longer needs a stored function object he should release it by setting it to the default. Thus a possibly embedded refcounting will lead to a release of resources not visible to the client:
storedFunc = MyCallbackFunc();
// -> destructing invisible callback object

Top1.10 Lambda expresssions

A lambda expression is an unnamed function (usually a small function), which is defined directly at the place of execution. You can avoid the effort to define a regular function or function object elsewhere. All relevant code can be concentrated at a single place.

Top1.10.1 Basic samples

Build the sum of all positive values within a list
std::list<int> values;
int sum;

std::for_each(values.begin(), values.end(),
 [&sum](int const & in_value){if (in_value > 0) sum+=in_value;}); 

std::cout << "nSum= " sum << std::endl;
Find first element greater than some value
std::vector<int> v;
v.push_back(4);
v.push_back(-4);
v.push_back(17);
v.push_back(2);
v.push_back(67);
v.push_back(7);

auto itPos = std::find_if(v.begin(),v.end(),
    [](int const & num)->bool {return num > 15;});

// Simplified syntax is also possible:
// auto itPos = std::find_if(v.begin(),v.end(),
//    [](int num){return num > 15;});

std::cout << "Found matching value " << *itPos <<
  << " at position " << std::distance(v.begin(), itPos)
  << std::endl;
Output:
Found matching value 17 at position 2

Top1.10.2 Allgemeine Syntax

Visibility of local scope:
  • [ ]
    local environment is not visible within the function
  • [=]
    all variables of local environmment are copied to function sccope
  • [&]
    all variables of local environmment are available as references within function sccope
  • [varA,&varB]
    varA is availablle as copy, varB as reference
  • [&,varA]
    varA is availablle as copy, all other variables are available as reference
  • [=,&varA]
    varA is available as reference, all other variables are available as copies

For more info see lambda functions

Top2 Class design

Top2.1 Inheritance - safely overriding base methods

Problem
Assume you have a derived class overriding some methods of a base class. On some dark day in the future you or someone else changes the signature of a base class method. If the derived class is not adjusted accordingly the connection to the base class method is destroyed:
  • the compiler does not complain (he does not know that you planned to override something)
  • At runtime when calling through a base class pointer simply the base class method is called and the derived method will no longer be called.
Solution: use attribute "override" to get compile time error
When using the optional attribute "override" the compiler knows you are trying to override something. He will emit an error if there is no matching base class method.

Base class providing some virtual methods:

class Base
{
public:
    virtual void DoSomething (int);
    virtual int DoSomethingElse(double);
};
Derived class with overrides:
class Derived : public Base
{
    // "override" ensures that there are matching base class methods

    // correct match with base class method
    virtual void DoSomething (int) override;

    // mismatch (wrong param type) -> compile error
    virtual int DoSomethingElse(int) override;
};
If the derived method does not have a matching base class method the compiler will say soemthing like:
error C3668: 'Derived::DoSomethingElse' : method with override specifier
  'override' did not override any base class methods

Rule:
When overriding some base class method always use attribute "override" to let the compiler know what you are planning.

Top2.2 Inheritance - final methods and classes

Final method implementation
If you are planning a class hierarchy you can decide that some base method shall receive a final implementation at some point in the hierarchy and all classes following in the inheritance chain are no longer allowed to override that method.

Base class providing some virtual methods:

struct SomeInterface
{
    virtual void DoSomething (int) = 0;
    virtual int DoSomethingElse (double) = 0;
};

class Base : public SomeInterface
{
public:
    virtual void DoSomething (int) override;

    // this is the optimal implementation which cannot
    // be improved by derived classes
    virtual int DoSomethingElse(double) override final;
};
Derived class with overrides:
class Derived : public Base
{
    // overriding is allowed
    virtual void DoSomething (int) override;

    // overriding is not allowed -> compile error
    virtual int DoSomethingElse(double) override;
};
If you are illegally trying to override a final method the compiler will say something like:
error C3248: 'Base::DoSomethingElse': function declared as 'final'
  cannot be overridden by 'Derived::DoSomethingElse'

Final class implementation
You can also define a whole class as final. Then you are not allowed to derive from that class:
class Derived final: public Base
{
};
When trying to create a more derived class:
class MoreDerived : public Derived
{
};
you will receive the following compile error:
error C3246: 'MoreDerived' : cannot inherit from 'Derived'
  as it has been declared as 'final'

Top2.3 Disallow copy or creation on heap

Disallow copy
class MyClass
{
public:
    // Ensure that the compiler generated
    // default cosntructor still exists
    // (despite of the definitions below which
    // would suppress the generation of the default
    // constructor)
    MyClass()=default;

    // Disallow copying via assignmment operator
    MyClass& operator= (MyClass const&)=delete;

    // Disallow copying via copy constructor
    MyClass (MyClass const&)=delete;
};
Disallow creation on the heap
class MyClass
{
public:
    // Disallow memory allocation on heap
    void* operator new (std::size_t)=delete;
};

Top3 New libraries

Top3.1 Compile-time fractional arithmetic: ratio

The following example compiles 1/2 + 1/3 = 5/6 and 1/2 * 1/3 = 1/6 at compile time:
#include <ratio>

typedef std::ratio<1,2> Num1;
typedef std::ratio<1,3> Num2;

typedef std::ratio_add<Num1, Num2> Sum;
typedef std::ratio_multiply<Num1, Num2> Product;

std::cout << "Sum     : " << Sum::num <<
    "/" << Sum::den << std::endl;
std::cout << "Product : " << Product::num <<
    "/" << Product::den << std::endl;
Output:
Sum     : 5/6
Product : 1/6

For more details see ratio - at CppReference.com

Remarks
Within Visual Studio 2012 (which does not yet fullly support C++11) you have to use Sum::type::num and Sum::type::den to get the result.

The class ratio can be used within chrono library to define the time unit as a fraction of seconds.

Top3.2 Date and Time: chrono

Top3.2.1 Waiting, timepoints and durations

  • Wait a duration of time
    #include <thread>
    #include <chrono>
    
    // wait for a duration of 100 ms
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    
  • Wait until a timepoint is reached
    // Calculate a timepoint 5 seconds in the future
    auto timepoint = std::chrono::system_clock::now() + std::chrono::seconds(5);
    
    // do something which needs some time
    
    // wait the rest of the remaining 5 seconds
    std::this_thread::sleep_until(timepoint);
    
  • Calculating durations
    // Calculated duration is of type chrono::seconds
    auto duration = std::chrono::hours(1) + std::chrono::minutes(2)
        + std::chrono::seconds(10);
    std::cout << "Calculated duration [sec]: " << duration.count() << std::endl;
    
    // Work day of 10 hours
    std::chrono::hours myWorkDay(10);
    std::cout << "Work day              [h]: " << myWorkDay.count() << std::endl;
    
    // Remaining work time in minutes
    auto remainingWorkTime = myWorkDay - std::chrono::minutes(5);
    std::cout << "Remaining work time [min]: " << remainingWorkTime.count()
        << std::endl;
    
    Output:
    Calculated duration [sec]: 3730
    Work day              [h]: 10
    Remaining work time [min]: 595 
    

Top3.2.2 Calendar calculations

Top3.2.2.1 Helper function to construct a date (time_t)

// Construct a date
time_t MakeDate (
	int in_day,    // 1, 2, ..., 31
	int in_month,  // 1, 2, ..., 12
	int in_year)   // 1900, 1901, ...
{
  std::tm timeinfo = std::tm();
  timeinfo.tm_mday = in_day;
  timeinfo.tm_mon  = in_month-1; // zero based index
  timeinfo.tm_year = in_year - 1900;
  std::time_t date = std::mktime (&timeinfo);
  return date;
}

Top3.2.2.2 Helper function to generate standard format for date and time

// Generate standard format for date/time using predefined format functions
// Possible result: "Tue Dec 31 11:47:13 2013"
std::string TimePoint2String (
    std::chrono::system_clock::time_point & in_timePoint)
{
    time_t t = std::chrono::system_clock::to_time_t(in_timePoint);

    char buffer [50];
    ctime_s(buffer,50,&t); // generate standard format

    std::string retVal = buffer;
    retVal.resize(retVal.size()-1); // remove line break

    return retVal;
}

Top3.2.2.3 Helper function to generate customized date format

// Generate custom date format
// Possible reults: "30.12.13", "30.12.2013",
// "Monday, 30.12.13", "30.12.13 23:59:59"

enum class WriteDate {NO, SIMPLE, WEEKDAY, CENTURY, WEEKDAY_CENTURY};
enum class WriteTime {NO, SIMPLE, SECOND};

std::string FormatAsDate (
    std::chrono::system_clock::time_point & in_timePoint,
    WriteDate in_writeDate = WriteDate::SIMPLE,
    WriteTime in_writeTime = WriteTime::NO)
{
    const char* weekDay[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
        "Thursday", "Friday", "Saturday"};

    time_t rawtime = std::chrono::system_clock::to_time_t(in_timePoint);
    struct tm timeinfo;
    localtime_s (&timeinfo, &rawtime );

    std::ostringstream oss;
    if (    (in_writeDate == WriteDate::WEEKDAY)
         || (in_writeDate == WriteDate::WEEKDAY_CENTURY))
    {
        oss << weekDay[timeinfo.tm_wday] << ", ";
    }

    oss << std::setfill('0') << std::setw(2) << timeinfo.tm_mday << "."
        << std::setfill('0') << std::setw(2) << timeinfo.tm_mon + 1 << ".";

    if (    (in_writeDate == WriteDate::CENTURY)
         || (in_writeDate == WriteDate::WEEKDAY_CENTURY))
    {
        oss << timeinfo.tm_year + 1900;
    }
    else
    {
        oss << timeinfo.tm_year % 100;
    }
    if ((in_writeDate != WriteDate::NO) && (in_writeTime != WriteTime::NO))
    {
        oss << " ";
    }

    if (in_writeTime != WriteTime::NO)
    {
        oss << std::setfill('0') << std::setw(2) << timeinfo.tm_hour << ":" 
            << std::setfill('0') << std::setw(2)<< timeinfo.tm_min;
        if (in_writeTime == WriteTime::SECOND)
        {
            oss << ":" << std::setfill('0') << std::setw(2)
                << timeinfo.tm_sec;
        }
    }

    return oss.str();
}

Top3.2.2.4 Converting timepoints to formatted calendar days

std::chrono supports calculation of timepoints and time durations. To get the real calendar date which is represented by a timepoint you have to convert to date format time_t with use of std::chrono::system_clock::to_time_t.

#include <ctime>
#include <sstream>
#include <iomanip>
#include <vector>

using namespace std::chrono;

// Hint: For the conversion of timepoint to type time_t
// see helper funtions TimePoint2String and FormatAsDate 

system_clock::time_point today = system_clock::now();
// add one day and some additional time
system_clock::time_point tomorrow = today
    + std::chrono::hours(25) + std::chrono::minutes(5);

// days is not predefined, so define it by yourself,
// unit of ratio is seconds
typedef std::chrono::duration<long,std::ratio<24*3600,1>> days;
system_clock::time_point threeDaysLater = today + days(3);

std::cout << "nStandard format:" << std::endl;
std::cout << "Today is    " << TimePoint2String(today) << std::endl;
std::cout << "Tomorrow is " << TimePoint2String(tomorrow) << std::endl;

std::cout << "nCustom format:" << std::endl;
std::cout << "Today is    " << FormatAsDate(today,
    WriteDate::WEEKDAY_CENTURY, WriteTime::SIMPLE) << std::endl;
std::cout << "Tomorrow is " << FormatAsDate(tomorrow,
    WriteDate::WEEKDAY_CENTURY, WriteTime::SIMPLE) << std::endl;

std::cout << "nCustom format simplified:" << std::endl;
std::cout << "Today is        " << FormatAsDate(today) << std::endl;
std::cout << "3 days later is " << FormatAsDate(threeDaysLater) << std::endl;
Output:
Standard format:
Today is    Tue Dec 31 11:47:13 2013
Tomorrow is Wed Jan 01 12:52:13 2014

Custom format:
Today is    Tuesday, 31.12.2013 11:47
Tomorrow is Wednesday, 01.01.2014 12:52

Custom format simplified:
Today is        31.12.13
3 days later is 03.01.14

Top3.2.2.5 Converting calendar days to timepoints to perform calculations

A given calendar day of type time_t can be converted to a timepoint with use of the function std::chrono::system_clock::from_time_t. After having performed some calculations with timepoints and durations you can convert back to the resulting calendar day.
std::cout << "n2012 is a leap year" << std::endl;
system_clock::time_point tpBeforeLeapDay = system_clock::
    from_time_t (MakeDate(28,2,2012));
system_clock::time_point tpLeapDay = tpBeforeLeapDay + std::chrono::hours(24);
std::cout << "Before leap day: " << FormatAsDate(tpBeforeLeapDay) <<
    std::endl;
std::cout << "Leap day       : " << FormatAsDate(tpLeapDay) << std::endl;

std::cout << "n2013 is not a leap year" << std::endl;
system_clock::time_point tpFirstMarch = system_clock::
    from_time_t (MakeDate(1,3,2013));
system_clock::time_point tpOneSecBefore =
    tpFirstMarch - std::chrono::seconds(1);
std::cout << "First day in march: " << FormatAsDate(tpFirstMarch,
    WriteDate::SIMPLE,WriteTime::SECOND) << std::endl;
std::cout << "One second before : " << FormatAsDate(tpOneSecBefore,
    WriteDate::SIMPLE,WriteTime::SECOND) << std::endl;
Output:
2012 is a leap year
Before leap day: 28.02.12
Leap day       : 29.02.12

2013 is not a leap year
First day in march: 01.03.13 00:00:00
One second before : 28.02.13 23:59:59

Top3.2.2.6 Clock characteristics

A specific clock is given by
  • the epoch, which is the starting point for time measurement (e.g. UNIX epoch 01.01.1970). Each timepoint of a clock is defined by a positive or negative duration added to the epoch of the clock.
  • the precision (=tick period) (e.g. milli seconds, nano seconds). The tick period (e.g. system::clock::period) is of type std:ratio and represents the fraction of seconds one tick is represented by.
  • the steady property. A clock is steady when it is not influenced by time adjustments (e.g. switching because of day light saving time).
    Warning: When sleeping for a timepoint of a not steady clock, the timeout period may be influenced dramatically (instead of waiting 5 seconds you may wait for an hour if you start waiting in the moment of time adjustment).
Depending on the properties of your environment there may be multiple predefined clock types:
  • system_clock
    the usual clock when dealing with calendar date and time, reflects local time, usually not steady
  • steady_clock
    guarantees to be steady
  • high_resolution_clock
    guarantees to have the shortest tick period possible on your system; may be identical to system_clock

The following code requests the properties for the system_clock:

// default contructor of time_point represents epoch of clock
// local time is considered!
std::chrono::system_clock::time_point epoch;

// Time period is given in fraction of seconds
// Now converting to fraction of milli seconds
double precisionMs =
    system_clock::period::num * 1000.0 / system_clock::period::den;

std::cout << "nInfo about system_clock" << std::endl;
std::cout << "epoch     : " << FormatAsDate(epoch,
    WriteDate::CENTURY,WriteTime::SIMPLE) << std::endl;
std::cout << "precision : "  << std::fixed
    << precisionMs << " ms" << std::endl;
std::cout << "steady    : " << std::boolalpha
    << system_clock::is_steady << std::endl;
Output:
Info about system_clock
epoch     : 01.01.1970 01:00
precision : 0.000100 ms
steady    : false

For more details see system_clock - usage info at CppReference.com

Top4 Containers

Top4.1 Tuples - storing N values of mixed type - std::tuple

A std::tuple is a generalization of a std::pair. You can store N values of any type within a tuple.

To access e.g. the second element within your tuple you can use std::get<1>(yourTuple). But as the access is through template functionality the used index has to be a compile time constant!

Using std::tuple_cat you can concatenate several tuples to one big tuple.

For more details see tuple - usage info at CppReference.com

Top4.1.1 Basic usage

// Define and init tuple explicitly
std::tuple<std::string,int,double> someTuple("ABC", 42, 3.14);

// Change some entries
// Restriction: used index must be a constant!
std::get<0>(someTuple) = "SomeTuple";
std::get<1>(someTuple)++;
std::get<2>(someTuple) -= 2;

// Write to stdout using template helper function
WriteTuple(someTuple);

// Create a tuple without explicit definition
auto otherTuple = std::make_tuple("OtherTuple", 2.987, 12, 56, true);
WriteTuple(otherTuple);
Output:
(SomeTuple / 43 / 1.14)
(OtherTuple / 2.99 / 12 / 56 / true)

Top4.1.2 References to other variables

A tuple can contain references to values stored elsewhere.
// There are some variables
int valA = 2;
int valB = 4;

// Create a tuple with references
auto refTuple = std::make_tuple("RefTuple", std::cref(valA), std::ref(valB));

// Change values
valA = 222;
// Change valB through tuple reference
std::get<2>(refTuple) += 5;
// Remark: "std::get<1>(refTuple)++;" is not
// possible because of const ref

WriteTuple(refTuple);
std::cout << "valA=" << valA << std::endl;
std::cout << "valB=" << valB << std::endl;

// Create tuple of (non const) references
auto refTuple2 = std::tie(valA, valB);
std::get<0>(refTuple2) = -2;
std::get<1>(refTuple2) = -4;
WriteTuple(refTuple2);
std::cout << "valA=" << valA << std::endl;
std::cout << "valB=" << valB << std::endl;
Output:
(RefTuple / 222 / 9)
valA=222
valB=9
(-2 / -4)
valA=-2
valB=-4

Top4.1.3 Extract parts of a tuple

You can assign selected elements of a tuple to other variables:
auto tuple = std::make_tuple("AnyTuple",3.14, 4711, true);

// Extract selected elements of a tuple
double pi=0;
int num=0;
std::tie(std::ignore, pi, num, std::ignore) = tuple;

// Remark: The returned value of std::tie
// is also a tuple which is not used here

std::cout << "pi=" << pi << std::endl;
std::cout << "num=" << num << std::endl;
Output:
pi=3.14
num=4711

Top4.1.4 Generic helper function to write a tuple to stdout

// Generic mechanismm to write a tuple to std out.
// Tuple can be of any length and may contain arbitrary types.
// Required: all types need to be streamable.

// Define a type for each unsigned integer value
// The type represents the index of the tuple element
template<std::size_t> struct Int2Type{};

// Write tuple element at index IDX
template <class TUPLE, size_t IDX>
std::ostream& WriteTupleElement(std::ostream& out, const TUPLE& t,
    Int2Type<IDX> )
{
    // Write element at position IDX
    // we also know that there is at least one element following
    // otherwise the specialized template would have been used
    out << std::get< IDX >(t) << " / ";

    // Recursive call to write next element
    return WriteTupleElement(out, t, Int2Type<IDX+1>());
}

// Specialization for last element, i.e. idx is size of tuple -1
template <class TUPLE>
std::ostream& WriteTupleElement(std::ostream& out,
    const TUPLE& t, Int2Type<std::tuple_size<TUPLE>::value-1> )
{
    return out << std::get<std::tuple_size<TUPLE>::value-1>(t);
}

// Template function to be callled by client code
template<typename TUPLE>
void WriteTuple(TUPLE t)
{
    // Choose format for all elements
    std::cout << std::fixed << std::setprecision(2) << "(";

    // Recursive call for all elements
    WriteTupleElement(std::cout, t, Int2Type<0>());

    // Add new line after last element
    std::cout << ")" << std::endl;
}

Top4.2 Array of fixed size - std::array

A std::array is a sequential container of fixed size which is conform to STL.

Always use a standard array

  • where you usually have used a C array
  • where you have used a std::vector and you did not need the possibility to change the container size at runtime

For more details see arrray - usage info at CppReference.com

Top4.2.1 Basic usage

Define your container type and size:
#include <array>

const int MY_ARRAY_SIZE = 5;
typedef std::array<int, MY_ARRAY_SIZE> MyArrayType;
Create and use array:
// Fully and explicitly initialized array
MyArrayType myArray = {1,2,3,4,5};

// Access array elements
myArray[0] = 4;
myArray.at(2) +=3;

Top4.2.2 Variants for initialization

// Uninitialized array,
// each element may have an arbitrary value
MyArrayType myArray1;

// Partly initialized array
// values: 1,2,3,0,0
MyArrayType myArray2 = {1,2,3};

// Zero initialized array
// values: 0,0,0,0,0
MyArrayType myArray3 = {};

Top4.3 Singly linked list - std::forward_list

A std::forward_list is a singly-linked list wiith the following properties
  • minimum storage requirements (e.g. compared to doubly linked list std::list)
  • fast insertion and removal of elements
  • NOT available: fast random acccess, backward iteration, push_back

For more details see forward_list - usage info at CppReference.com

Basic usage
Define your list type:
#include <forward_list>

typedef std::forward_list<int> MyListType;

Create and use forward_list:
// Define empty list
MyListType myList;

// Fill list (values: 1,2,5)
myList.push_front(5);
myList.push_front(2);
myList.push_front(1);

// Insert missing values 3 and 4 after value 2
// values: 1,2,3,4,5
auto itPos2 = std::find(myList.begin(),myList.end(),2);
auto itPos3 = myList.insert_after(itPos2,3);
auto itPos4 = myList.insert_after(itPos3,4);

// Remove the following element
// values: 1,2,3,4
myList.erase_after(itPos4);

// Remove first element
// values: 2,3,4
myList.pop_front();

// Access the remaining first element (=2)
int num = myList.front();

Top5 Algorithms

A selection of nnew algorithms is presented in the sections below.

In addition there are a number of other new algorithms, which will be only listed here. For more information please klick on the external links:

Top5.1 All, none, at least one element fulfills a property - std::all_of/none_of/any_of

The algorithms std::all_of, std::none_of, std::any_of check whether the elements within a given range of elements fulfill some requirement:

  • std::all_of
    all of the elements fulfill a given property
  • std::none_of
    none of the elements fulfills a given property
  • std::any_of
    there is at least one element which fulfills a given property

For more details see usage info at CppReference.com

Basic usage
#include <algorithm>
...
std::vector myNumbers;
myNumbers.push_back(2);
myNumbers.push_back(3);

bool anyNumGreater3 = std::any_of(
	myNumbers.begin(),myNumbers.end(), greater3);
// anyNumGreater3: false

myNumbers.push_back(4);

anyNumGreater3 = std::any_of(
	myNumbers.begin(),myNumbers.end(), greater3);
// anyNumGreater3: true

// chek range via lambda function
bool allNumWithinRange = std::all_of(
	myNumbers.begin(),myNumbers.end(),
	[](int i) {return i>1 && i<4;});
// allNumWithinRange: false

// check 
bool noneIsNegative = std::none_of (
	myNumbers.begin(),myNumbers.end(),
	[](int i) {return i<0;});
// noneIsNegative: true

Top5.2 Fill range with sequentially increasing values - std::iota

std::iota can be used
  • to set a start value for the first element of a range, each of the following elements will be set to the next incremented value
  • to set a destination range of elements according to the values from a source range of elements (instead of the value the iterator position of the source range is incremented)
Example
// Construct list of 5 integers (with value 0)
std::list<int> myList(5);

// Set list values to 5,6,7,8,9
std::iota(myList.begin(),myList.end(),5);

// Create vector with same size as the list
std::vector<int> myVec(myList.size());

// Transfer the list elements to the vector
std::iota(myVec.begin(),myVec.end(),myList.begin());
For more details see usage info at CppReference.com

Top6 Smart Pointers - automatic release of resources

Smart pointers are used to simplify releasing of resources. Common principle for all smart pointer types is the automatic releasing of a resource when the smart pointer gets out of scope, i.e. when its destructor is called. This mechanism also works in the presence of exceptions without the need of writing special handling code.

Depending on your needs choose one of the following smart pointer types:

  • for exclusive access to a resource use unique_ptr
  • for shared access to a resource use shared_ptr. There may be multiple clients all taking ownership of a resource. When the last client has released the resource will automatically be deleted / freed.
  • for access to a resource without taking ownership use weak_ptr. There may be the need of using a resource without keeping it alive. Main motive: avoid circular references to allow shutdown of resources.

Top7 Move semantics and rvalue references

Top7.1 Motivation

Sometimes object creation can be very expensive. When creating a copy from an object then instead of copying all data, a simple transfer of ownership for the data would be more desirable. This applies especially to the following situations:
  • your object copy is created from a temporary object which is not available for further usage anyway
  • your object copy is created from a regular object, but you as the programmer do not plan to use the source object anymore

Top7.2 Example - no optimization

Assume you have some data struct which is expensive for copying:
struct BigData
{
    BigData (std::string const & in_data)
        : m_data (in_data)
    {
        std::cout << "BigData-Constructor " << in_data << std::endl;
    }

    ~BigData ()
    {
        std::cout << "BigData-Destructor" << std::endl;
    }

    // possibly a very long string
    std::string m_data;
};
typedef std::unique_ptr BigDataUp;
This expensive data struct is contained within some class:
struct SomeObject
{
    // default constructor
    SomeObject()
    {std::cout << "SomeObject-DefaultConstructor" << std::endl;}

    // constructor with argument
    SomeObject(std::string const & in_data)
    : m_upBigData (new BigData(in_data))
    {std::cout << "SomeObject-Constructor" << std::endl;}

    // copy constructor
    SomeObject (SomeObject const& rhs)
    {
        std::cout << "SomeObject-CopyConstructor" << std::endl;
        if (rhs.m_upBigData)
        {
            // Copy big data
            m_upBigData.reset(new BigData(rhs.m_upBigData->m_data));
        }
    }

    // assignment operator
    SomeObject& operator= (SomeObject const& rhs)
    {
        std::cout << "SomeObject-AssignmentOp" << std::endl;
        if (this != &rhs)
        {
            m_upBigData.reset(); // delete old contents
            if (rhs.m_upBigData)
            {
                // Deep copy of big data
                m_upBigData.reset(new BigData(rhs.m_upBigData->m_data));
            }
        }
            return *this;
    }

    // Unique ptr to big data stored on heap
    BigDataUp m_upBigData;
};
Client code creating copies from SomeObject:
{
    std::cout << "nAssignment from temporary object" << std::endl;
    SomeObject a;
    a = SomeObject("XYZ");
}

{
    std::cout << "nAssignment from regular object" << std::endl;
    SomeObject a("ABCDEF");
    SomeObject b;
    b = a;
}
Result: Big data has to be created always twice:
Assignment from temporary object
SomeObject-DefaultConstructor
BigData-Constructor XYZ
SomeObject-Constructor
SomeObject-AssignmentOp
BigData-Constructor XYZ
BigData-Destructor
BigData-Destructor

Assignment from regular object
BigData-Constructor ABCDEF
SomeObject-Constructor
SomeObject-DefaultConstructor
SomeObject-AssignmentOp
BigData-Constructor ABCDEF
BigData-Destructor
BigData-Destructor

Top7.3 Example - now using rvalue references

Add optimized move copy constructor and move assignment operator to your class
struct SomeObject
{
...

    // move copy constructor
    SomeObject(SomeObject && rhs)
        : m_upBigData (std::move(rhs.m_upBigData))
    {
        std::cout << "SomeObject-MoveCopyConstructor" << std::endl;
    }

    // move assignment operator
    SomeObject& operator= (SomeObject&& rhs)
    {
        std::cout << "SomeObject-MoveAssignmentOp" << std::endl;
        if (this != &rhs)
        {
            m_upBigData.reset();
            // transfer ownership of big data
            m_upBigData = std::move(rhs.m_upBigData);
        }
        return *this;
    }
}
The client code has to be slightly modified:
{
    std::cout << "nMove assignment operator implicitly called" << std::endl;
    SomeObject a;
    a = SomeObject("XYZ"); // temporary object is an rvalue
}

{
    std::cout << "nMove assignment operator explicitly called" << std::endl;
    SomeObject a("ABCDEF");
    SomeObject b;
    // std::move converts to rvalue thus allowing use of move assignment op
    b = std::move(a);
    // from here on "a" has lost its data!
    // contents were moved to "b"
}
The you can observe that big data will only be created once for each case:
Move assignment operator implicitly called
SomeObject-DefaultConstructor
BigData-Constructor XYZ
SomeObject-Constructor
SomeObject-MoveAssignmentOp
BigData-Destructor

Move assignment operator explicitly called
BigData-Constructor ABCDEF
SomeObject-Constructor
SomeObject-DefaultConstructor
SomeObject-MoveAssignmentOp
BigData-Destructor
RValueReferences-End

Top7.4 Distinguishing lvalues and rvalues

Intuitive definition ("almost" true)
  • an lvalue is an expression that may appear on the left or on the right hand side of an assignment
  • an rvalue can only appear onthe right hand side of an assignment
Second definition
  • an lvalue is an expression that refers to a memory location. You can access this memory with use of the & operator
  • an rvalue is an expression that is not an lvalue
Examples
int a;
int b;

// a and b are lvalues
a = b;
b = a;

// a*b is an rvalue
a = a*b;
a*b = 42; // compile error!


int& MyFuncA();
int MyFuncB();

// MyFuncA is an lvalue
int c = MyFuncA
MyFuncA() = 42;         // OK!
int* pInt = &MyFuncA(); // OK!

// MyFuncB is an rvalue
int d = MyFuncB();
MyFuncB() = 17;           // compile error!
int* pInt2 = &MyFunccB(); // compile error!

Top7.5 Rvalues and optimization

The concept of rvalues and lvalues is used to decide at compile time whether a function can be called for an lvalue or for an rvalue (which allows more optimization). A function can support both overloads. If there is no overload for an rvalue the version for lvalues will be called in all situation or a compile error will occur (e.g. a temorary object can not be passed as non const reference)

New syntax for rvalue params:

void SomeFunction(X&& in_x);
In most cases the relevant rvalue functions are copy constructors and asignment operators.

With SomeFunction(std::move(x)) the programmer simply says to the compiler: regard x as an rvalue and try to use the optimized overload if it is available.

Top8 Multithreading

Top8.1 Running multiple threads

Keywords:
thread this_thread promise future async packaged_task
Running multiple threads
Support for writing of multi threaded code is given by a number of language features:
Basic control
  • std::thread
    you can explicitly write and start your own thread function
  • std::promise and std::future
    as a standard mechanism of exchanging both return values and exceptions between your thread function and some environment code you can write the results to a promise. The interested code can access these results with use of a future which is connected to the promise.
Advanced features
  • std::async
    you can leave the details about asynchronous code execution to the C++ runtime. Depending on your processor's characteristics and the complexity of the code to execute the code may be executed synchronoussly or really asynchronous within a separate thread. As you are always accessing results through a future this will work for both the synchronous and the asynchronous case.
  • std::packaged_task
    you can store execution code within packaged_tasks for later execution (e.g. by passing them to some threads from your thread pool as soon as they become available). Again results are accessed via futures which are attached to the package_tasks.

Top8.2 Safe access to shared data

When multiple threads are working on the same data there is the danger that one thread changes the data while another thread tries to read and possibly also change the data at the same time. To avoid such race conditions proper means have to be applied.

Full protection - the safe way
  • Mutexes and locks
    To allow both changing and reading of shared data by arbitrary threads at any time you can protect data access with use of mutexes and locks. The mutex ensures that only one thread at a time can access the data.

Protect only where really necessary
All synchronization means cause some kind of complexity and will have an impact on execution performance. Sometimes there are simpler possibilities to ensure proper multi threading.
  • multiple reader threads - no protection at all
    If it is possible for your program flow then first fully initialize shared data before reader threads can access them. As long as the data will not change while being accessed from one or more reader threads threre is no need for any synchronization.
  • Safe initialization of data - std::call_once, static variables
    Within multithreaded environments the trigger for initializing some data may come from different threads at the same time (e.g. request for a singleton instance which is created on such a request).
  • Protecting simple integral values - std::atomic
    Sometimes your shared data consists only of a single integral value (e.g. some counter, some instance pointer). Instead of having to use a separate mutex you can simply define the data as being "atomic".

Top8.3 Wait and signal - std::condition_variable

Within multithreaded environments a system's reaction to some internal or external trigger may consist of a series of small steps executed by multiple threads. The steps may be executed at least partly in parallel. Within such a scenario there is often the need that a thread has to wait until some preprocessing has reached some state before he can start or proceed with his own processing.

A simple approach for the waiting thread might be "polling": he repeatedly checks some shared data until he recognizes that the data's state allows to start his own processing. If the state is not yet reached he sleeps for a small time interval and then repeats the check.

The typical disadvantages of this approach are:

  • The repeated checks consume cpu load. Furthermore accessing shared data may require the need for repeatedly locking access to the data which may delay the work of other active threads which have to process the data.
  • The reaction time depends on the time interval used for sleeping. Assume that at some point in time the conditions to start a thread's work are reached. But the thread may sleep for that time interval before he repeats the check and recognizes that he can start his part of processing.
To avoid these disadvantages you can use
  • std::condition_variable
    Principle: Thread A waits on a condition, i.e. the thread is switched to inactive mode. Thread B finishes his actions and signals that the condition has become true. As a consequence thread A is triggered and continues his execution.