Modern C++

Modules (C++20)

"Modules are orthogonal to namespaces."

lvalues and rvalues

An lvalue refers to an object that persists beyond a single expression. You can think of an lvalue as an object that has a name. All variables, including nonmodifiable (const) variables, are lvalues. An rvalue is a temporary value that does not persist beyond the expression that uses it.

A function call can be an lvalue if and only if the return value is a reference.


  • static_cast
  • reinterpret_cast
  • dynamic_cast
  • const_cast

Arrays can be implicitly converted to pointers without casting: there is no implicit conversion from pointers to arrays. int* can be implicity converted to int const*: there is no implicit conversion from int const* to int*.

You can static cast a derived class pointer to a base class pointer but not the other way around.

  • Only static_cast (or C-style casts) can be used to cast an int to an enum. Only reinterpret_cast (or C-style casts) can be used to cast an int to a pointer or a pointer to an int.

Rule of three/five

If you declare any of copy, copy assignment or destructor then you should declare them all. Similarly, for C++11 onwards: rule of 5.

See wiki/Rule of three.

  • C++: Understand how rule of 5 (rule of 3 in pre-C++11) is the best way to write exception-safe classes. Understand why it's a good idea even without exceptions.
  • Function local variables are not accessible in the try handler.

See rule of three/five/zero.

class base_of_five_defaults
    base_of_five_defaults(const base_of_five_defaults&) = default;
    base_of_five_defaults(base_of_five_defaults&&) = default;
    base_of_five_defaults& operator=(const base_of_five_defaults&) = default;
    base_of_five_defaults& operator=(base_of_five_defaults&&) = default;
    virtual ~base_of_five_defaults() = default;

The rule of the big four and a half

  • If you have written a (non-default) destructor for a class you should implement the copy constructor and assignment operator for the class; or mark them as deleted.
  • Similarly, if you have written either a (non-default) copy constructor or assignment operator for the class you must write a destructor.
  • If your class can be moved you must implement both the move constructor and move assignment operator; or mark them as deleted.

Classes and structures

The difference between a class and a struct is only the default accesses specifier: public: for struct and private: for class.


  • Make destructors noexcept (they are anyway)
  • Mark move constructor noexcept


results matching ""

    No results matching ""