The C++ Standard Library: Errata for 3rd and 4th Printing |
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> {
by:
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()
||
(p1.lastname()==p2.lastname()&&
p1.firstname()<p2.firstname());
Page 140, Section 5.11.2:
Replace
void
insert (const Cont& coll, Iter pos, const T& value)
by
void
insert (Cont& coll, const Iter& pos, const T& value)
Page 149, Section 6.2.1:
Replace
capacity()
returns the number of characters
by
capacity()
returns the number of elements
Page 159, Section 6.2.6
In the example at the bottom of the page, Substitue c.at(5)
by c[5]
because in contrast to the following text c.at(5)
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()
||
(p1.lastname()==p2.lastname()&&
p1.fistname()<p2.firstname());
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,
Note that the member functions called by mem_fun_ref and mem_fun and passed as argument to bind1st or bind2nd must be constant member functions. Unfortunately, the C++ standard library does not enable bind1st and bind2nd to use adapters for nonconstant member functions.
For example:
class Elem {
public:
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 ...
by
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
numeric_limits<int>::max()
by
std::numeric_limits<std::streamsize>::max()
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>
by
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
std::map<int,float,less<int>,
SpecialAlloc<std::pair<const
int,float> > > m;
// a string with special allocator
std::basic_string<char,std::char_traits<char>,SpecialAlloc<char>
> s;
and:
// 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
by
Section 15.4
You can find an example of a user-defined
allocator at http://www.josuttis.com/cppcode/.
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/