If you want to have narrowing conversion, you should do it explicitly not implicitly according to the Python rule from The Zen of Python: Explicit is better than implicit. The guideline support library (GSL) has two cast to express your intent: gsl::narrow_cast and gsl::narrow.

What is bad about the C-cast? You don't see which cast is actually performed. If you perform a C-cast, a combination of casts will be applied if necessary. Roughly speaking, a C-cast starts with a static_cast, continues with a const_cast, and finally performs a reinterpret_cast.

Of course, you know how I will continue: explicit is better than implicit.

Including the GSL, C++ offers eight different named casts. Here are they including a short description:

static_cast: conversion between similar types such as pointer types or numeric types

const_cast: adds or removes const or volatile

reinterpret_cast: converts between pointers or between integral types and pointers

dynamic_ cast: converts between polymorph pointers or references in the same class hierarchy

std::move: converts to a rvalue reference

std::forward: converts to a rvalue reference

gsl::narrow_cast: applies a static_cast

gsl::narrow: applies a static_cast

What? std::move and std::forward are casts? Le's have a closer look at the internas of std::move:

static_cast<std::remove_reference<decltype(arg)>::type&&>(arg)

First the type of the argument arg is determined by decltype(arg). Then all reference are removed and two new references added. The function std::remove_reference is from the type-traits library. I have already written a few posts to the type-traits library. At the end we will always get a rvalue reference.

If you don't believe me, their is a footnote in the C standard [ISO/IEC 9899:2011] (subclause 6.7.3, paragraph 4) which is also relevant for the C++ standard: The implementation may place a const object that is not volatile in a read-only region of storage. Moreover, the implementation need not allocate storage for such an object if its address is never used.

Did I mention mutable? mutable is one of the most unknown features in C++. mutable allows you to differentiate between bitwise and logical constness. What?

Imagine you want to implement the interface to a telephone book. For simplicity reasons, the entries should be in an std::unordered_map.

My telephone book (1) is extremly small. Usually, a telephone book is quite big and updating it is quite an expensive operation (2). This means updating a printed telephone book will happen only once a year in Germany. From the conceptional view, the inqueries to the teleBook (3) should be const.This is not possible, because the unordered_map is modified in the method getNumber. Here is the proof in red ellipses.

The qualifier mutable allows you to differentiate between bitwise and logical constness. The telBook is logical but not bitwise const.

Get your e-book at leanpub:

The C++ Standard Library

Concurrency With Modern C++

Get Both as one Bundle

With C++11,C++14, and C++17 we got a lot of new C++ libraries. In addition, the existing ones are greatly improved. The key idea of my book is to give you the necessary information to the current C++ libraries in about 200 pages.

C++11 is the first C++ standard that deals with concurrency. The story goes on with C++17 and will continue with C++20.

I'll give you a detailed insight in the current and the upcoming concurrency in C++. This insight includes the theory and a lot of practice with more the 100 source files.

Get my books "The C++ Standard Library" (including C++17) and "Concurrency with Modern C++" in a bundle.

In sum, you get more than 550 pages full of modern C++ and more than 100 source files presenting concurrency in practice.