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

C++17 - The Complete Guide

Errata of the First Edition

April 30, 2022

This is the errata of the 1st printing of the book C++17 - 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 34, 4.2 Using Extended Aggregate Initialization: 2019-12-20

Replace:

by:

Page 43, 5.3.1, Value Categories Since C++11: 2020-09-26

A few examples for value categories should be clarified:

Examples of lvalues are:

...
Examples of xvalues are:

Page 102, 10.2.2 Other Compile-Time if Examples: Compile-Time if for Tag Dispatching

A typename is missing twice (before C++20).
Twice replace:

    using cat = std::iterator_traits<Iterator>::iterator_category;

by

    using cat = typename std::iterator_traits<Iterator>::iterator_category;

Page 143, 15.2.2 std::optional<> Operations: Comnparisons: 2019-12-20

Replace:

    If both operands are objects without a value, they are considered to be equal (== yields true and all other comparisons yield false).

by:

    If both operands are objects without a value, they are considered to be equal (==, <=, and >= yield true and all other comparisons yield false).

Page 176, 17.2.2 Any Operations, Changing the Value: 2019-10-08

Replace:

a.emplace{std::in_place_type<std::string>, "hello"};
        // a contains value of type std::string
a.emplace{std::in_place_type<std::complex<double>>, 4.4, 5.5};
        // a contains value of type std::complex<double>

by:

a.emplace<std::string>("hello");
        // a contains value of type std::string
a.emplace<std::complex<double>>(4.4, 5.5);
        // a contains value of type std::complex<double>

Page 196, 19.4.2, String View Operations: Modifying a String View: 2020-09-25

You have to convert all string views to be able to call + for them.

Replace:

One of the operands has to be a string:
  auto s2 = std::string(sv1) + sv2;   // OK

by:

Both of the operands have to be strings:
  auto s2 = std::string(sv1) + std::string(sv2);   // OK

Page 202, 20.1.1,checkpath2.cpp: 2019-08-29

All output of path p should use p.string().

Page 238, 20.4.4 Filesystem Modifications: Table 20.15. Creating and Deleting Files: 2019-12-20

Replace:

    create_hard_link(old, new) | Creates another filesystem entry to for the existing file from

by:

     create_hard_link(to, new) | Creates another filesystem entry new for the existing file to

Page 316, 26.3, Container-Support of Incomplete Types: 2019-10-08

    The link to http://drdobbs.com/184403814 is gone. Instead, you can use: http://web.archive.org/web/20190305220304/http://www.drdobbs.com/184403814


Typos

To have the printed version of this edition available at CppCon 2019, I had to send a version to the printer where not all proof reading was done yet. Therefore, in the second part of the printed CppCon Edition you will find several formulations that are no proper English.
For this reason, I only list a few significant typos here.
The electronic version of the CppCon Edition was completely proof read (so that hopefully only a few issues are left).

Page xvii, Acknowledgments

s/ Thomas, Köppe / Thomas Köppe /

Page 18, 1.3 Enable Structured Bindings with Write Access:

s/return std::move(c.firstname();) }/return std::move(c.firstname()); }/

Page 33, Chapter 4 Aggregate Extensions

s/ you no longer need te equal sign / you no longer need the equal sign /

Page 63, 8.2 Defined Expression Evaluation Order

s/ e1.f is guaranteed to be evaluated before a1, a2, and a3 now. / e1 is guaranteed to be evaluated before a1, a2, and a3 now. /

Page 65, 8.2 Defined Expression Evaluation Order, right before 8.3:

s/ "value " / "value: " / (twice)

Page 68, 8.6 UTF-8 Character Literals:

s/ u6'6'/ u8'6' /

Page 73: 8.9 Preprocessor Condition __has_include

s/ if (__has_include(<filesystem>) / if (__has_include(<filesystem>)) /

Page 78, 9.1 Use of Class Template Argument Deduction

s/ class tuple; / class tuple { /

Page 79, 9.1.1 Coyping by Default:

s/ std::vector v2{v1}; // v2 also is vector<int> / std::vector v2{v1}; // v2 also is vector<int> /

s/ std::vector vv{v, v}; // vv is vector<vector<int>> / std::vector vv{v1, v2}; // vv is vector<vector<int>> /

Page 85, 9.2.1 Using Deduction Guides to Force Decay

s/ we pass type const char(&)[6] so that T is deduced as const char[6]: / we pass type const char(&)[6] so that T is deduced as char[6]: /

Page 113, 11.2.2 Supported Operators

s/ void callFoo(const Types&... args) / void callFoo(Types&&... args) /

Page 114, 11.2.2 Supported Operators

s/ (hashCombine(seed,"World")),hashCombine(seed,42)) / hashCombine(seed,"World")),hashCombine(seed,42) /

Page 114, 11.2.2 Supported Operators

s/ to use it as an unordered set / to use it in an unordered set /

Page 177, 11.2.3 Using Fold Expressions for Types

s/ std::is_same_v<int,MyType> / std::is_same_v<int,Size> /

Page 136, 15.1.1 Optional Return Values

s/ The program asInt() contains a function / The program contains a function asInt() /

s/ signaling that we don not have / signaling that we do not have /

Page 140, 15.2.2 std::optional<> Operations: Construction

s/ provided the underlying supports copying / provided their underlying type supports copying /

Page 143, 15.2.2 std::optional<> Operations: Accessing the Value

s/ meaning that the contained is not copy constructed / meaning that the contained value is not copy constructed /

Page 151, 16.2 Using std::variant<>: std::monostate

s/ Their own purpose / Their only purpose /

Page 155, 16.3.2 std::variant<> Operations

s/ For std::variant<>, You / For std::variant<>, you /

Page 167: 16.4.2 Other Heterogeneous Collections with std::variant

A closing } is missing in the last code example.

Page 168, 16.4.3, Comparing variant Polymorphism:

s/ which approach is faster for you On different platforms, / which approach is faster for your code. On different platforms, /

Page 175, 17.2.2 Any Operations: Construction

s/ // a2 contains value of type const char* / // a3 contains value of type const char* /

Page 183, 18.2.2 std::byte Operations: I/O with std::byte

s/ if (! std::cin.fail()) { / if (! strm.fail()) { /

Page 198, 19.5.1 Using String Views instead of Strings

At the end of the section, the first example call of sort() should also have the std::execution::par argument.

Page 205, 20.1.2 Switch Over Filesystem Type: Namespace fs

s/ as s shortcut / as a shortcut /

Page 226, 20.3.5 Path Modifications: Table 20.7

s/ p.concat(sub) / p.concat(str) /

Page 234, 20.4.2 File Status: Table 20.12

Remove p at the end of the symlink_status(p) effect

Page 244, 20.4.6 Other Filesystem Operations

s/ auto currentDir{std::filesystem::current_path(); / auto currentDir{std::filesystem::current_path()}; /

Page 260, 22.1.1, lib/parforeach.cpp: Table 22.3

s / // initialize NumElems values without square root: / // initialize numElems values without square root: /

Page 267, 22.5 Overview of Parallel Algorithms

s/ copy_backward() move_backward() / copy_backward(), move_backward() /

Page 274, 22.6 Motivation for New Algorithms for Parallel Processing: Parallelization for Non-Associative Operations

s/ 1; 2 or 3 / 1, 2, or 3 /

Page 277, 22.6.1, transform_reduce() for Filesystemn Operations

s/ given as command-line arguments / given as command-line argument /

Page 283, 285: 23.2.2 std::transform_reduce()

s/ InputIterator beg, InputIterator end) / InputIterator beg, InputIterator end, /

Page 286, 23.2.2, lib/transform_reduce2.cpp:

s / // process sum of differences of squared elements: / // process sum (concatenation) of concatenated digits: /

Page 287, 289: 23.2.3 std::inclusive_scan() and std::exclusive_scan()

s/ InputIterator beg, InputIterator end) / InputIterator beg, InputIterator end, /

s/ T initVal) / T initVal, /

s/ BinaryOp op, / BinaryOp op) /

s / std::exclusive_scan / std::exclusive_scan() /

s/ and write them to the soure starting with / and write them to the destination range starting with /

Page 289: 23.2.4 std::transform_inclusive_scan() and std::transform_exclusive_scan()

s/ InputIterator beg, InputIterator end) / InputIterator beg, InputIterator end, /

s/ T initVal) / T initVal, /

s/ BinaryOp op, / BinaryOp op) /

Page 294, 24.1.1, Using Searchers with search()

s/ To use this searchers / To use these searchers /

Page 296, 24.2, Using General Subsequence Searchers

s/ std::cout << "found subsequence at << " beg - coll.begin() << '\n'; / std::cout << "found subsequence at " << beg - coll.begin() << '\n'; /

Page 297, 24.3, Using Searcher Predicates

s/ searches / seachers / (twice)

Page 298, 24.4, Afternotes

s/ These searches / The seachers /

Page 300, 25.1.1 Generic size() function

s/ last5 / printLast5 / (twice)

Page 301, 25.1.2, Generic empty() Function, Footnote:

s/ However, using std::size() for such an empty C array does not compile. / However, using std::empty() for such an empty C array does not compile. /

Page 311, 26.1. Node Handles

s/ By introducing the ability to splice node / By introducing the ability to splice a node /

Page 316, 26.3.3 try_emplace()

s/ The is no definition of whether/ There is no definition of whether /

Page 332, 28.3.1

s/ lcm(x, x) / lcm(x, y)

Page 332, 28.3.1 Greatest common divisor and least common multiple

s/ returning / returns / (twice)

Page 332, 28.3.2 3-Argument Overloads of std::hypot()

s/ returning / returns /

Page 355, 29.2 Defining Custom Memory Resources

In pmr/tracker.hpp the second constructor should initialize the members in the opposite order to avoid warnings:

s/ : prefix{std::move(p)}, upstream{us} { / : upstream{us}, prefix{std::move(p)} { /

Page 358, 29.2.1 Equality of Memory Resources

The code of do_is_equal() should again check for an equal upstream as done before.

Page 370, 30.2.1 Implementing Aligned Allocation Before C++17

in comment: s/ of, if none exists / or if none exists /

Page 375: 30.2.2 Implementing Type-Specific operator new(): When Is operator new() Called?

After the return in operator new remove: ::operator delete(p);

Page 377,

s/ ::operator delete(p2, std::align_val_t{64}); // !!! / ::operator delete(p1, std::align_val_t{64}); // !!! /

s/ MyType32::operator delete(p1, std::align_val_t{64}); // !!! / MyType32::operator delete(p2, std::align_val_t{64}); // !!! /

Page 383, 30.4. Tracking all ::new Calls

s/ I this example / In this example /

Page 401, 33.1 std::invoke<>():

s/ call(printT / call(print / (twice)

Page 412, 35.2.7, Deprecated Library Features:

s/ codecvt> / <codecvt> /

 


Home of the C++17 book