Nicolai M. Josuttis: solutions in time  The C++ Standard Library: Errata for 3rd and 4th Printing

The C++ Standard Library - A Tutorial and Reference

Errata for the 3rd and 4th Printing
Jun 09, 2001

This is the errata for the 3rd and 4th printing of the book The C++ Standard Library by Nicolai M. Josuttis. It covers all errors that were found until the 5th printing came out. Thus, you will find additional errors in the erratas for later printings.

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

Please note: This list may portray the book as containing many errors. But keep in mind that the book has about 800 pages with about 240.000 words. As I am not perfect I couldn't do better, and in my opinion it is severe to expect significantly fewer bugs. To cite one reader: "Thanks again and I'm going to write a short review of the book for Amazon contradicting whoever said it had lots of errors".


Page 12 and 13, Section 2.2.1
On both pages replace:
    template <class T>
    class MyClass<T> {
    template <class T>
    class MyClass {

Pages 29/30, Section 3.3.2
The qualification with std:: is missing on several places of example code:
In the middle of page 29 you have to qualify exception, cerr, and endl.
- On top of page 30 you have to qualify string and out_of_range.

Page 124, Section 5.8.2:
The sorting criterion personSortCriterion() has to be implemented as follows:
    return p1.lastname()<p2.lastname() ||

Page 140, Section 5.11.2:
    void insert (const Cont& coll, Iter pos, const T& value)
    void insert (Cont& coll, const Iter& pos, const T& value)

Page 149, Section 6.2.1:
    capacity() returns the number of characters
    capacity() returns the number of elements

Page 159, Section 6.2.6
In the example at the bottom of the page, Substitue by c[5] because in contrast to the following text would throw an exception instead of causing undefined behavior if no sixth element exists.

Page 202, Section 6.6.2
c.insert(pos,elem) doesn't return whether it succeeded. Thus, strike "and whether it succeeded" in the second row of Table 6.31.

Page 205, Section 6.6.2
The second example contains some errors:
- Remove the declaration of tmp_pos
- Replace each occurence of identifier c by coll

Page 219, Section 6.7.2
In cont/carray.hpp, size_t and ptrdiff_t has to get qualified by std::.

Page 273, Section 7.4.2
In iter/backins.cpp there is a nasty problem with the following statement:

  copy (coll.begin(), coll.end(),   // source
        back_inserter(coll));       // destination

Because the back inserter inserts elements into a vector, these insertions might invalidate all other iterators referring to the same vector. Thus, the algorithm invalidates the passed source iterators while running. To avoid this behavior, you have to reserve enough space so that the reallocation won't happen. So, insert before the statement above:

  // reserve enough memory to avoid reallocation
coll.reserve (2*coll.size());

Page 279, Section 7.4.3
In iter/ostriter.cpp, the following include directive for class ostream_iterator is missing:

#include <iterator>

Page 288, Section 7.5.2
At the definition of MyIterator, ptrdiff_thas to get qualified by std::.

Page 295, Section 8.1.1:
The sorting criterion PersonSortCriterion has to be implemented as follows:
    return p1.lastname()<p2.lastname() ||

Page 303, Section 8.1.4
In example fo/removeif.cpp replace the comma at the end of the call of remove_if() by a semicolon.

Page 307, Section 8.2.2
Thoughout this section I state that member function for mem_fun_ref and mem_fun have to be constant member functions. This is not true. There is only a bug in combination with bind1st and bind2nd. Thus,

For example:

class Elem {
    void print (int i) const { }
    void modify (int i) { }

int main()
    vector<Elem> coll(2);
    for_each (coll.begin(), coll.end(),
              bind2nd(mem_fun_ref(&Elem::print),42));   // OK
for_each (coll.begin(), coll.end(),
              bind2nd(mem_fun_ref(&Elem::modify),42));  // ERROR

Page 315, Section 8.3.1
In fo/compose1.cpp the header file <iterator> for ostream_iterator is missing.

Page 319, Section 8.3.2
In fo/compose3.cpp the header file <cctype> for the C version of toupper() is missing.

Page 329, Section 9.2.2
Replace "stable_sort() is also based historically on heapsort" by "stable_sort() is based historically on mergesort".

Page 354, Section 9.5.3
Replace adjacent_find_if by adjacent_find (adjacent_find() is overloaded with both forms).

Page 358, Section 9.5.4
The second form of mismatch() returns the first corresponding elements for which the binary predicate op(elem,cmpElem) yields false. Thus, change last word of the second bullet.

Page 391, Section 9.8.3
next_permutation() and prev_permutation() return false, if the elements have "normal" order and true otherwise. Thus, change true and false of the third bullet and in the footnote.

Page 478, Section11.1.2
On the last row, replace with a signed type by with an unsigned type.

Page 487, Section 11.2.6
replace char* p = s[3]; by char* p = &s[3];

Page 489-517, Sections 11.2.8 - 11.3.7
some missing qualifications with std::

Page 493, Section 11.2.10
Of course, if width() is greater than 0, operator << writes at least width() characters.

Page 493, Section 11.2.10
getline() does not ignore leading whitespaces. Thus, replace

    This function ignores leading whitespaces and reads all characters until ...
    This function reads all characters (including leading whitespaces) until ...

Page 504, Section 11.2.14
In string/icstring.hpp:
size_t has to get qualified by std::
- Preprocessor directives to enable multiple includes are missing
- operator << should be declared as inline
See string/icstring.hpp for an updated version.

Page 524, Section 11.3.10
Of course, if strm.width() is greater than 0, operator << writes at least width() characters.

Page 525, Section 11.3.10
getline() does not respect width(). So, strike the first item of the list that describes how long characters are extracted by getline(). This was a simple error due to a copy-and-paste from operator >>.

Page 595, Section 13.3.2
Replace std::complex c; by std::complex<double> c;

Pages 608, Section 13.5.1
There is another difference between get() and getline() for input streams: If getline() reads lines with more than count-1 characters, it sets failbit. Thus, to read again you have to call clear().

Pages 609 and 614, Sections 13.5.1 and 13.6.2:
There is a contratiction in the standard regarding istream::ignore(). Once int is used as type of the first argument, once streamsize is used. According to the current defect report list streamsize seems to be right. Thus, replace each occurence of

Page 654, Section 13.12.1
Of course, the output of Fraction vat(16,100) is:  VAT: "16/100 "

Page 670, Section 13.13.3:
In io/outbuf1x.hpp substitute
  class traits = char_traits<charT>
  class traits = std::char_traits<charT>

Page 707, Section 14.4.1
In the example of numeric parsing
replace std::ios_base::ios_state by std::ios_base::iostate
- add > before (loc) so that the line reads as follows:
      = std::use_facet<std::num_get<charT,InIt> >(loc);
See i18n/numget.cpp for a complete supplementary example program.

Page 714, Section 14.4.3
In Table 14.15 replace space in last row by none. In addition, last but second and last but third rows are identical.

Page 727, Section 15.1
Usually, you have to pass arguments to allocators and qualifications with std are missing. Thus, the examples have to be as follows:

// a vector with special allocator
std::vector<int,SpecialAlloc<int> > v;

// an int/float map with special allocator
         SpecialAlloc<std::pair<const int,float> > > m;

// a string with special allocator
std::basic_string<char,std::char_traits<char>,SpecialAlloc<char> > s;


// special string type that uses special allocator
typedef std::basic_string<char,std::char_traits<char>,
                          SpecialAlloc<char> > xstring;

// special string/string map type that uses special allocator
typedef std::map<xstring,xstring,less<xstring>,
                 SpecialAlloc<std::pair<const xstring,xstring> > > xmap;

Page 731, Section 15.2
In the example for temporary buffers, ptrdiff_t has to get qualified by std::.

Page 737, Section 15.4
In util/defalloc.hpp replace delete((void*)p)) by delete((void*)p).

Page 740, Section 15.5.2
The member function destroy() for allocators, of course, calls the destructor. Thus, replace


Section 15.4
You can find an example of a user-defined allocator at


Page xix: s/fogive/forgive/

Page xix: s/comp.std.c++.moderated/comp.lang.c++.moderated/

Page 16: s/That a function not throw/That a function does not throw/

Page 80: s/as long as it returns true/as long as it returns false/

Page 83: s/a STL container/an STL container/

Page 87: s/arbitray/arbitrary/

Page 109: s/to cout by calling operator >>/to cout by calling operator <</

Page 114: s/the real ends/the real end/

Page 124: s/that behave as functions/that behave like functions/

Page 133: s/multiply<int>/multiplies<int>/

Page 137: /The most security/The highest security/

Page 143: s/a type of reference manual/a kind of reference manual/

Page 143: s/bitmaps/bitsets/

Page 144: s/rather than managing references to it/rather than managing references to them/

Page 148: s/the implementation use a/the implementation uses a/

Page 175: s/the type is defined as a template class/the types are defined as class templates/

Page 182: s/the with following arguments/with the following arguments/

Page 183: s/multisets allows duplicates/multisets allow duplicates/

Page 185: s/exceptions handling/exception handling/

Page 194: s/the type is defined as a template class/the types are defined as class templates/

Page 226: s/Table 6.9/Table 6.33/

Page 277: s/of a useful supplementation/of the need for a supplementation/

Page 283: s/someone who you respect./someone whom you respect./

Page 345: s/find three consecutive elements with value 4/find four consecutive elements with value 3/

Page 346: s/find three consecutive elements with value greater than 4/find four consecutive elements with value greater than 3/

Page 409: s/They may have significant better performance/They may have significantly better performance/

Page 429, second bullet: s/The first form/The second form/

Page 446: s/back() returns ... (the element that was inserted first)/back() returns ... (the element that was inserted last)/

Page 478: s/as an optional second character argument/as an optional third character argument/

Page 506: s/vectors implementations/vector implementations/

Pages 512-523: s/Note that cstr may not be a null pointer/Note that cstr must not be a null pointer/

Page 513: s/the contents of buf may be not/the contents of buf might not be/

Page 586: s/The shift operators << for input and >> for output/The shift operators << for output and >> for input/

Page 589: s/Using stream buffers/By using stream buffers/

Page 594: s/less priority/lower priority/

Page 611: s/the read character is accessed simply by using the dereference operator/the read character is accessed simply by passing c by reference/

Page 624: s/1.23456789e-001/1.23456789e-01/

Page 627: s/provides three class templates/provides four class templates/

Page 658: s/by using the stream buffer's member function sputn()/by using the stream's member function write()/

Page 693: s/(JIT)/(JIS)/

Page 705: s/instant/instance/

Page 720: s/To understanding/To understand/

Page 721: s/a very few/very few/

Page 723: s/need to produce/needed to produce/

Home of the C++ Library book