|
| C++23 - The Complete Guide: Errata of First Edition |
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.
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
}
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 /