C++11StdLib  The C++ Standard Library, 2nd Edition: Errata for 3rd and later printings

The C++ Standard Library - A Tutorial and Reference, 2nd Edition

Errata
January 31, 2016

This is the errata of the third and later printings of the book The C++ Standard Library, 2nd Edition by Nicolai M. Josuttis. It extends the errata for the previous printings.

The errata is organized in the following way:
- The first part lists technical errors
- The second part lists typos (including stylistic changes due to consistency etc.)


Errors

Page 24 (3.1.6): s/a b, a backslash, an n, a c, a double quote/a b, a backslash, a n, a c, an open paren, a close paren, a double quote/

Page 81 (util/sharedptr2.cpp): 2013-11-22
Just a clarification: The call of std::remove() is the call of a standard C function declared in <cstdio> to delete files. Unfortunatelly, I don't have these C functions described in the book and for this reason you also can't find an entry in the index for the remove() called here.

Page 87, Figure 5.2: 2016-01-30
The arrows to mother and father refer to the wrong objects ...

Page 279 (7.3.4 Exception Handling): 2014-08-29
There is one exception to the exception guarantees for push_back() and emplace_back() (first item listed): If vector elements have no copy constructor, then even a throwing move constructor is used, which can bring the vector into an undefined state.

Page 308 (cont/findbefore.hpp): 2014-08-29
In functions find_before() and find_before_if() replace InputIterator by ForwardIterator everywhere. The reason is that we iterate over elements using different iterators expecting to have the same elements/values at the same position, which is not guaranteed for input iterators.

Page 310 (cont/forwardlistsplice1.cpp): 2015-10-10
Replace
  // splice 3 from l1 to l2 before 99
  l1.splice_after(pos2, l2, //
destination
                  pos1);    //
source
by
  // splice 3 from l1 to l2 before 99
  l2.splice_after(pos2,      // destination
                  l1, pos1); // source

Page 328 (cont/multiset1.cpp): 2014-05-03
The changed output has to be as follows:
   6 5 5 4 3 2 1
   4 inserted as element 5
   1 2 3 4 4 5 5 6
   2 element(s) removed
   3 4 4 6

Page 369 (Table 7.53): 2014-08-29
Remove the listed reverse iterator functions c.rbegin(), c.rend(), c.crbegin(), c.crend(), because as written reverse iterators are not supported for unordered containers.

Page 437 (9.2.3 Forward Iterators): 2014-08-29

In the example code, there is a closing } missing for the inner if statement.

Page 692 (13.2.17 Strings and Vectors): 2015-10-10
In the last paragraph I give the example for special string implementations using reference counting. But as written in 13.2.16, this optimization is no longer allowed since C++11. Thus, replace the sentence:

For example, strings are often implemented by using reference counting; vectors never are.

as follows:

For example, strings often are implemented with optimizations to avoid too many heap allocations (e.g. using reference counting before C++11 or using the "short string optimization", which holds strings directly in the object provided they are reasonable short); vectors never are.

Page 703 (13.3.7, void string::append (initializer-list)):

The return type must be string&:    string& string::append (initializer-list)

Page 744 (Chapter 15, Recent Changes with C++11): 2013-11-22
Add a bullet point saying that a successful open() for file streams now implies clear() so that any EOF or fail bits are cleared (see http://lwg.github.io/issues/lwg-defects.html#409)

Page 798 (io/cat1.cpp and followig text): 2013-11-22
Remove the call of clear() after the loop because since C++11 a successful open() for file streams implicitly calls clear(), and change the following words into:

Note that before C++11 after the processing of a file, file.clear() had to be called before calling open() again to clear the state flags that are set at end-of-file. The reason is that open() never cleared any state flags before C++11. This was also the case if you use the same stream to open different files and read them until the end.

Page 897 bottom (16.4.4 Character Encoding Conversion): 2013-11-212
Since C++11, the C++ standard library also requires two additional standard conversions with codecvt<>:

  1. The specialization codecvt<char16_t, char, mbstate_t> converts between the UTF-16 and UTF-8 encoding schemes.
  2. The specialization codecvt <char32_t, char, mbstate_t> converts between the UTF-32 and UTF-8 encoding schemes.

As a consequence, these functions are now more useful than I wrote on top of page 898. But I have to find out details, because I am not an expert in this area of the standard.

Page 968/969 (18.2.1: "Thread IDs"): 2015-10-10
This example has a possible race because after starting thread master in the main thread we set masterThreadID, while in the started thread performing doSomething() we read masterThreadID. Thus we might read masterThreadID although it might not be set or is about to be set. There is no easy fix. Probably the best is to change doSomething() as follows:

void doSomething()
{
  ...   // code that ensures that masterThreadID is set before we read it
  if (std::this_thread::get_id() == masterThreadID) {
    ...
  }
  ...
}

Page 969 (18.2.2, concurrency/promise1.cpp): 2014-02-14
In the example is a data race caused undefined behavior according to the standard: The problem is that get_future() and set_value() might be called in parallel and that these are not only const member function. Thus, you have to call get_future() before starting the thread.
In addition, you should should call set_value_at_thread_exit() and set_exception_at_thread_exit() instead of set_value() and set_section() because that's safer in general.
See concurrency/promise1.cpp for the new version.

Page 1032 [Abrahams:RValues]: 2016-01-31
The Link [Abrahams:RValues] does not longer exists, but you can restore it with: https://web.archive.org/web/20121221100546/http://cpp-next.com/archive/2009/09/move-it-with-rvalue-references


Typos

Page 8 (2.1): s/This books covers/This book covers/

Page 34 (3.2): s/any identifier of a template is considered to be a value except if it is qualified by typename/any identifier defined by a template is considered to be a value unless it is qualified by typename/

Page 42 (4.3.1): s/in an exception specification Note, however, that/in an exception specification. Note, however, that/

Page 51 (4.3.2): s/This allows to handle exceptions as follows:/This allows one to handle exceptions as follows:/

Page 65 (5.1.1 make_pair()): s/template <template T1, template T2>/template <typename T1, typename T2>/

Page 79 (5.2.1): s/For example, assigning the nullptr ... to pNico or resizing the vector .../For example, assigning the nullptr ... to pNico and resizing the vector .../

Page 112 (5.2.6): s/All comparison operators compare the raw pointers the shared pointers internally use /All comparison operators compare the raw pointers the unique pointers internally use /

Page 146 (table 5.21): s/d1 <= d2 | Return whether duration d1 is not shorter than duration d2/d1 >= d2 | Return whether duration d1 is not shorter than duration d2/

Page 151 (5.7.3): s/cout << "this program runs: " << s.count() << " seconds" << endl;/cout << "this program runs: " << sec.count() << " seconds" << endl;/

Page 262 (7.2.1): s/std::array<int,5> a({ 1, 2, 3, 4, 5, 6 }); // ERROR/std::array<int,6> a({ 1, 2, 3, 4, 5, 6 }); // ERROR/

Page 266 (7.2.2 before "Iterator Functions"): Strike paragraph starting with "Note that this code is OKonly in single-threaded environments." because you can't modify the size of array<>s.

Page 306 (Table 7.32): Row with c.erase_after(beg,end): s/Removes all elements of the range [beg,end)/Removes all elements of the range (beg,end)/

Page 306 (Table 7.32): Remove "since C++11" twice

Page 312 (cont/forwardlist1.cpp): s/insert six new element at the beginning of list2/insert six new elements at the beginning of list2/

Page 324 (7.7.1, "Inserting and Removing Elements"): s/the type of status is as follows: std::pair<std::set<float>::iterator,bool>/the type of status is as follows: std::pair<std::set<double>::iterator,bool>/

Page 342 (7.8.2, "Inserting and Removing Elements"): s/To remove an element that has a certain value/To remove an element that has a certain key/

Page 362 (bottom): s/prepare for 100/max_load_factor() elements/prepare for 100*max_load_factor() elements/

Page 381 (cont/buckets.hpp): s/for (auto idx=0; idx != cont.bucket_count(); ++idx) {/for (auto idx=0u; idx != cont.bucket_count(); ++idx) {/

Page 411 (8.6 container::end()): s/Note that unordered containers also provide begin() and cbegin() for a numeric argument/Note that unordered containers also provide end() and cend() for a numeric argument/

Page 435 (9.2.1): s/For this reason, all reading iterators might have the additional ability to write./For this reason, all reading iterators might have the additional ability to write./

Page 436 (9.2.2): In "InputIterator begin, end" and "while (pos != end)": make end italics

Page 437 (9.2.3): In "while (pos1 != end)": make end italics

Page 532 (algo/searchn1.cpp): s/no four consecutive elements with value 7 found/no three consecutive elements with value 7 found/

Page 550 (11.5.5): s/ • is_sorted()_until returns/ • is_sorted_until() returns/

Page 601 (11.9.2 partial_sort_copy()): s/If the size of the source range [sourceBeg,sourceEnd) is not smaller than the size of the destination range [destBeg,destEnd), all elements are copied and sorted./If the size of the source range [sourceBeg,sourceEnd) is not greater than the size of the destination range [destBeg,destEnd), all source elements are copied and sorted./

Page 689 (13.2.14): s/The criterion itself takes the current local into account./The criterion itself takes the current locale into account./

Page 695 (13.3.2): string::string(InputIterator beg, InputIterator end) is listed twice

Page 702: (13.3.7 string::append(const char*)): s/Both operations append the characters of the C-string cstr./Both operations append the characters of the C-string cstr (not including ’\0’)./

Page 703 (13.3.7, string::append): s/Both operations return returns *this./Both operations return returns *this./

Page 704: (13.3.7 string::insert(const char*)): s/Inserts the characters of the C-string cstr/Inserts the characters of the C-string cstr (not including ’\0’)/

Page 706 (13.3.7): s/string::replace (begin_iterator beg, begin_iterator end,/string::replace (const_iterator beg, const_iterator end,/

Page 717 (Chapter 14): s/ • Tokenize a character according to a token separator/Tokenize a string according to a token separator/

Page 753 (15.3): s/In C and C++, operators << and >> are used for shifting bits of an integer to the right or the left, respectively. /In C and C++, operators >> and << are used for shifting bits of an integer to the right or the left, respectively./

Page 761 (15.4.3): s/Because cin is being used in the context of a condition, its operator void* is called/Because cin is being used in the context of a condition, its operator bool() is called/

Page 823 (15.12.3): s/even when resize() is left/even when redirect() is left/

Page 834 (15.13.3): s/because putchar() only accepts char only/because putchar() accepts char only/

Page 852 (Figure 16.1): s:/USC-2/UCS-2/ and s/USC-4/UCS-4/

Page 935 (Table 17.10): multiples times s/Arcus/Inverse/

Page 940 (17.2.4): s/ • The arcus (inverse) operations/ • The arc (inverse) operations/

Page 1017 (Table 18.11): row "++1, a++": s/returns copy of a or a+1/returns copy of a+1 or a/;  row "--a, a--": s/copy of a or a-1/copy of a-1 or a/

Page 1106 (S1.1, footnote 1): s/Before C++11, type unsigned long was not provided/Before C++11, type unsigned long long was not provided/


Home of the C++ Library book, 2nd edition