C++ Primer Plus Reading Notes

Function Templates

A function template is a generic function description that uses generics to define functions, where the generic types can be replaced with concrete types. By passing types as parameters to the template, the compiler can generate functions for those types.

Explicit Specialization: Provides a specialized template definition for a specific type. When the compiler finds a specialization that matches a function call, it uses that definition instead of looking for a generic template.

  • For a given function name, you can have non-template functions, template functions, explicit specializations, and their overloads.
  • Explicit specialization prototypes and definitions should begin with template<> and identify the type by name.
  • Specializations take priority over regular templates, and non-template functions take priority over both specializations and regular templates.

Keyword decltype (C++11)
Sometimes we want to deduce the type of a variable from an expression without actually initializing the variable with the expression’s value. To address this, C++11 introduced the decltype type specifier, which inspects and returns the data type of its operand — the compiler analyzes the expression and determines its type, but does not evaluate the expression.

template<class T1, class T2>
void printplus(T1 a, T2 b) {
    decltype(a+b) c = a + b;        // without decltype, we can't determine whether a+b yields T1, T2, or some other type
    cout << c;
}

Friend

In C++, non-member functions cannot directly access private members and private member functions. However, sometimes we need certain functions or classes to bypass this restriction — that’s the purpose of the friend mechanism. There are three kinds of friends:

  • Friend functions
  • Friend classes
  • Friend member functions

Exception Mechanism

C++ exceptions are a response to exceptional situations that occur during program execution. Exceptions provide a way to transfer control from one part of a program to another. In C++, the primary mechanism for catching exceptions is try-catch.

C++11 added the noexcept keyword to indicate that a function does not throw exceptions:

double marm() noexcept;     // marm() doesn't throw an exception

Using this keyword is essentially the programmer making a promise to the compiler: don’t worry, this function won’t throw.

Smart Pointers

The earliest smart pointer was auto_ptr, but it is now deprecated. The currently recommended smart pointers are unique_ptr, shared_ptr, and weak_ptr. How should you choose among them?

If the program needs multiple pointers to the same object, use shared_ptr. If the program does not need multiple pointers to the same object, use unique_ptr. weak_ptr is a special case — it is typically used in conjunction with shared_ptr. It can point to an object owned by a shared_ptr without incrementing the reference count, which means the object pointed to by a weak_ptr may have already been destroyed.

C++11

We’ve already touched on some C++11 features above; here are a few more. This is not an exhaustive list, just a selection.

  1. New types: long long, unsigned long long, char16_t, char32_t.

  2. The null pointer nullptr — recommended over 0 for better type safety.

  3. New range-based for loop.

  4. New smart pointers: unique_ptr, shared_ptr, weak_ptr.

  5. Rvalue references && and move semantics.

  6. Lambda expressions.

  7. Parallel programming.

Boost

An open-source library collection that includes many commonly used libraries such as logging and threading.