Josuttis C++23  C++23 - The Complete Guide: Errata of First Edition

C++23 - The Complete Guide

Errata of the First Edition

August 25, 2026

This is the errata of the 1st printing of the book C++23 - The Complete Guide by Nicolai M. Josuttis.
It covers all errors that were found.

The errata is organized in the following way:
- The first part lists technical errors
- The second part lists typos

Usually the latest electronic version covers all issues of this errata.


Errors

Page 201, 14.5.1 slide Views: 2026-08-23

The fact that slide views do not propagate constness is missing in the overview (note that slide views can only be used const if they do not cache):

Propagates constness: Never

Page 222, 14.6.1 chunk Views: 2026-08-23

Chunk views have no default constructor.
Remove the default constructor in Table 14.10:

chunk_view v{}   |   Creates a chunk_view that refers to a default constructed range

Pages 245/250, 14.7.4 cartesian_product Views: 2026-08-23

The entry when cartesion product veiws are common is missing:

Page 245 on the overview fix as follows:

Is common range: If the first range is common or is sized and supports random access

Page 250 Special Characteristics of cartesian_product Views fix as follows:

Replace:

Note that a cartesian_product view is common (has same type for iterator and sentinel)
only if their underlying range is a sized range and a common range.
To harmonize types, you might have to use a common view.

by:

Note that a cartesian_product view is common (has same type for iterator and sentinel)
only if their first underlying range is either a common range or it is a sized random-access range.

Page 389, 21.5.4 reserve() and capacity() for Flat Containers: 2026-08-25

Flat maps have member function for the keys and the values, but the extracted containers have data members. Therefore:

Replace:

std::flat_map<std::string, double> fmap;
...
auto newCapa = fmap.keys().capacity() * 5; // raise capacity by a factor of 5
auto data = std::move(fmap).extract();     // temporarily extract the underlying vectors
data.keys().reserve(newCapa);              // raise capacity of the vector for the keys
data.values().reserve(newCapa);            // raise capacity of the vector for the values
fmap.replace(std::move(data.keys()),       // move the vectors back into the flat map
             std::move(data.values()));

by:

std::flat_map<std::string, double> fmap;
...
auto newCapa = fmap.keys().capacity() * 5; // raise capacity by a factor of 5
auto data = std::move(fmap).extract();     // temporarily extract the underlying vectors
data.keys.reserve(newCapa);                // raise capacity of the vector for the keys
data.values.reserve(newCapa);              // raise capacity of the vector for the values
fmap.replace(std::move(data.keys),         // move the vectors back into the flat map
             std::move(data.values));

Page 456, 24.4.1 Motivation for std::start_lifetime_as<>(): 2026-08-18

Replace:

  Data* dp = *reinterpret_cast<Data*>(bytes); // does not start the lifetime of an object

by:

  Data* dp = reinterpret_cast<Data*>(buf);    // does not start the lifetime of an object

Page 257, 24.4.3 Using std::start_lifetime_as_array<>(): 2026-08-18

Replace:

  for (int i = 0; i < 10; ++i) {
    std::cout << dp->x << '/' << dp->y << '\n';
// OK
  }

by:

  for (int i = 0; i < 10; ++i) {
    std::cout << (dp+i)->x << '/' << (dp+i)->y << '\n';
// OK
  }


Typos

Page 112, 11.1.1 Creating and Printing a std::stacktrace

s/ hasArr / arrHas /

Page 120, 11.2.2 Type std::stacktrace_entry

s/ std::uint_least32_t / std::uint_least32_t /

s/ operator bool() yields true if the entry is empty. / operator bool() yields true if the entry is not empty. /

Page 423, 22.2.2 Preprocessor Directive #warning

s/ NULL and EOF should not be used / NULL and EOF cannot be used /

Page 426, 22.4.1 Using if consteval

s/ i: 72 / x: 72/

s/ i gets the value 42 / x gets the value 72 /

s/ int x = foo(); // runtime context => 42 / int x = foo(); // runtime context => 72 /

s/ c gets the value 72 / c gets the value 42 /

s/ constexpr int c = foo(); // compile-time context => 72 / constexpr int c = foo(); // compile-time context => 42 /

Page 428, 22.4.3 Runtime versus Compile-Time Context

s/ static int sx = foo(); // compile-time context => 72 / static int sx = foo(); // compile-time context => 42 /

s/ const int cx = foo(); // compile-time context => 72 / const int cx = foo(); // compile-time context => 42 /


Home of the C++23 book