The C++ Standard Library: Errata for 5th to 13th printings |
This is the errata for the 5th to 13th printings
of the book The
C++ Standard Library by Nicolai
M. Josuttis.
It extends the errata for the previous printings.Thus, you will find additional
errors in the erratas for later printings.
Please, note the
- hints for Visual C++ users.
- hints for GCC/G++ users.
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 54, Section 4.2.6
For auto_ptr::release() one
bullet is missing:
- Sets the value of the auto_ptr
to zero.
Page 61, Table 4.2:
min() returns for floating
point-types the minimum positive normalized value.
Page 100, Section 5.4.1
The algorithm to find the order of two values inside a collection does not
handle the case that one or both might be missing correctly. The correct version
is as follows:
pos25 = find (coll.begin(), coll.end(), // range 25); // value pos35 = find (coll.begin(), pos25, // range 35); // value if (pos25 != coll.end() && pos35 != pos25) { /* pos35 is in front of pos25 * so, only [pos35,pos25) is valid */ ... } else { pos35 = find (pos25, coll.end(), // range 35); // value if (pos35 != coll.end()) { /* pos25 is in front of pos35 * so, only [pos25,pos35) is valid */ ... } else { // 25 and/or 35 not found ... } }
Page 101, Section 5.4.1
The switch statement dereferences pos,
which is an error if pos is coll.end().
Thus, the statements after calling find_if()
have to be as follows:
if (pos == coll.end()) { // no element with value 25 or 35 found ... } else if (*pos == 25) { // element with value 25 comes first pos25 = pos; pos35 = find (++pos, coll.end(), // range 35); // value ... } else { // element with value 35 comes first pos35 = pos; pos25 = find (++pos, coll.end(), // range 25); // value ... }
Page 107, Section 5.5.2
In stl/ioiter1.cpp
the header file for stream iterators is missing:
#include <iterator>
Page 109, Section 5.5.3
In stl/riter1.cpp
the header file for stream iterators is missing:
#include <iterator>
Page 111, 112, 115, Section 5.6.1,
5.6.2
In stl/remove1.cpp, stl/remove2.cpp, and stl/remove3.cpp
the header file for stream iterators is missing:
#include <iterator>
Page 122, Section 5.8.2
By definition, 0 and 1 are not prime numbers. Thus, for these values
isPrime() should return false
instead of true.
Page 124, Section 5.8.2
In stl/sort1.cpp, the sorting criterion in personSortCriterion()
is wrong. It has to return:
return p1.lastname()<p2.lastname()
||
(p1.lastname()==p2.lastname()
&&
p1.firstname()<p2.firstname());
Page 135, Section 5.10.2
The sentence "All containers create internal copies of their elements
and return copies of those elements. is not correct. In fact, the
member functions at(), front(),
back(), and operator []
return references if available.
Page 140, Section 5.11.2
The auxiliary insert() function
does not work because we use pos
(as iterator of coll) as iterator
for an insertion into tmp. Thus,
the second line inside insert() has to be as follows:
coll.insert(pos,value);
// modify
Page 156, Section 6.2.5
In cont/vector1.cpp the header file for stream iterators is missing:
#include <iterator>
Page 159, Section 6.2.6
At the end of the definition of class std::vector<bool>::reference
right in the middle of page 159 there is a semicolon missing.
Page 159, Section 6.2.6
In the example at the bottom of the page, Substitute 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 164, Section 6.3.4
In cont/deque1.cpp the header file for stream iterators is missing:
#include <iterator>
Page 172, Section 6.4.4
In cont/list1.cpp the header file for stream iterators is missing:
#include <iterator>
Page 176, Section 6.5:
For the definition of strict weak ordering a fourth property is missing:
4. It has to have transitivity of equivalence, which
means roughly: If a is equivalent to b and b is equivalent to c, then a is equivalent
to c.
This means for operator <: If !(a<b)
&& !(b<a) is true and !(b<c)
&& !(c<b) is true then !(a<c)
&& !(c<a) is true.
This means for a predicate op():
If op(a,b), op(b,a), op(b,c), and op(c,b) all yield false then op(a,c) and op(c,a)
yield false.
Page 186, Section 6.5.4
In cont/set1.cpp the header files for algorithms and stream iterators
are missing:
#include <algorithm>
#include <iterator>
Page 189, Section 6.5.4
In cont/mset1.cpp the header files for algorithms and stream iterators
are missing:
#include <algorithm>
#include <iterator>
Page 197, Section 6.6.2
In the definition of StringFloatMap,
the second occurrence of string
also has to get qualified by std::.
Page 202, Section 6.6.2
In Table 6.31 replace
c.erase(elem)
| Removes all elements with value elem
and returns the number of removed elements
by
c.erase(key)
| Removes all elements with key
and returns the number of removed elements
Page 209, Section 6.6.5
In the output of cont/map1.cpp
the tabulator characters were replaced by spaces.
Page 218, Section 6.7.2
In cont/array1.cpp the header files for stream iterators is missing:
#include <iterator>
Page 228/229, Section 6.9
In cont/sortset.cpp and cont/sortvec.cpp the header file for
stream iterators are missing:
#include <iterator>
In addition, please note the hints
for gcc/g++ users.
Page 234, Section 6.10.3
container::count()
has logarithmic complexity.
Page 257, Section 7.2.5
last sentence: replace "even number" by "odd number"
Page 282, Section 7.4.3
In iter/advance2.cpp the header file for stream iterators is missing:
#include <iterator>
Page 295, Section 8.1.1
In fo/sort1.cpp, the sorting criterion PersonSortCriterion
is wrong. It has to return:
return p1.lastname()<p2.lastname()
||
(p1.lastname()==p2.lastname()
&&
p1.firstname()<p2.firstname());
Page 311/312, Section 8.2.4
In fo/fopow1.cpp the header file for stream iterators is missing:
#include <iterator>
In addition, the ostream_iterator
has to be instanciated for float.
Thus, in both calls the 3rd parameter for transform()
has to be: ostream_iterator<float>(cout," ")
Page 332, Section 9.3
In algo/algostuff.hpp the header file for stream iterators is missing:
#include <iterator>
Page 339 and 340, Section 9.5.2
For all arguments and return types min_element()
and max_element() have ForwardIterator
instead of InputIterator.
Page 344, Section 9.5.3
For all arguments and return types
both forms of search_n()
have ForwardIterator
instead of InputIterator.
Page 354, Section 9.5.3
For all arguments and return types
both forms of adjacent_find()
have ForwardIterator
instead of InputIterator.
Page 360, Section 9.5.4
The complexity of lexicographical_compare()
incorrectly has a factor of 2. Thus, replace
2*min(numberOfElements1,numberOfElements2)
by
min(numberOfElements1,numberOfElements2)
Page 366, Section 9.6.1
In algo/copy3.cpp the header file for stream iterators is missing:
#include <iterator>
Page 380, Section 9.7.1
The descriptions of remove_copy()
and remove_copy_if() are misleading.
Replace the second sentence of the first item by:
It copies each element in the source range [beg,end) that is not equal to value into the destination range starting with destBeg.
Replace the second sentence of the second item by:
It copies each element in the source range [beg,end) for which the unary predicate op(elem) yields false into the destination range starting with destBeg.
Page 385, Section 9.7.2
In algo/unique3.cpp the header file for stream iterators is missing:
#include <iterator>
Page 391, Section 9.8.3
!!! There are two forms of next_permutation() and prev_permutation() missing
where you can submit the sorting criterion as third argument. The argument has
to be a binary predicate as for lexicographical_compare() on page 360.
Page 429, Section 9.11.1
Swap comments on top as follows:
multiplies<int>(),
//
outer operation
plus<int>()) //
inner operation
Page 448, Section 10.2.3
Replace
explicit queue::stack (const Container& cont)
by
explicit queue::queue (const Container& cont)
Page 457, Section 10.3.3
Remove the semicolon between the parameter list and function body of push().
Page 471, Section 11
Saying that the type of string literals is const
char* ist not quite right. Strictly speaking, the original type of a
literal such as "hello"
is const char[6]. However, this
type automatically converts ("decays") to const
char*, so that you can almost always use (and see) const
char* in declarations. However, when working with templates the difference
might matter because for reference template parameters decay doesn't occur (see
our new template book :-).
Page 481, Section 11.2.2
Replace
copy() | Copies
or writes contents to a C-String
by
copy() | Copies
or writes contents to a character array
Page 492, Section 11.2.10
Item "1.": Operator >> skips whitespace if the skipws flag
is set; thus, strike "not".
Page 502, Section 11.2.13
In string/unique.cpp the header file for stream iterators is missing:
#include <iterator>
Page 512, Section 11.3.5
Operator[] for constants
has return type const char&
instead of char.
Page 518, Section 11.3.7
The string::erase()
functions for iterator arguments return iterators. Thus, twice replace string&
by iterator and replace in the
second bullet "They return the
first character" by "They
return the position of the first character".
Page 547, Section 12.2
For the Blitz web site see: http://www.oonumerics.org/blitz/.
In addition, see http://www.oonumerics.org
for many other useful sites and links about numeric processing in C++.
Page 553, Section 12.2.1
In num/val2.cpp vc
has to be defined with 9 as initial size:
valarray<double>
vc(9);
Page 617, Section 13.7.2
In the example at the bottom, all identifiers except b
have to get qualified by std::.
Page 622, Section 13.7.5
In the example after Table 13.20 you have to replace std::ios::hex
by std::hex and std::ios::dec
by std::dec. Otherwise, instead
of changing the base the value of the flags are written.
Page 670, Section 13.13.3
In io/outbuf1x.hpp, you have to qualify int_type
as subtype of traits. This is
because names in template argument dependent base classes are not found when
the class template is defined. Thus, twice replace int_type
by typename traits::int_type.
Page 673, Section 13.13.3
In io/outbuf2.hpp, the constructor of class fdostream
is buggy because &buf is
passed to the ostream constructor
before buf is initialized. This might cause a core dump. The correct implementation
is as follows:
fdostream
(int fd) : std::ostream(0), buf(fd) {
rdbuf(&buf);
}
Instead, you might use Ron's
Member Idiom.
Page 678 and 679, Section 13.13.3
In io/inbuf1.hpp:
In underflow(),
the return statements have to be as follows:
return
traits_type::to_int_type(*gptr());
instead of:
return
*gptr();
Otherwise, it might happen that the
return value is promoted to EOF
by accident.
In addition, memmove() has to be used instead of memcpy() because it might happen that source and destination area overlap.
Page 706, Section 14.4.1
For the initialization of np
there is a > missing. The
correct statement has to be:
// get
numeric output facet of the loc
locale
const std::num_put<charT,OutIt>& np
= std::use_facet<std::num_put<charT,OutIt>
>(loc);
Page 727, Section 15.1
Fix the type definitions as follows (std::
in front of basic_string and
"> >" instead
of ">>" before
xmap):
// special string type that uses
special allocator
typedef std::basic_string<char,std::char_traits<char>,
MyAlloc<char>
> xstring;
// special string/string map type
that uses special allocator
typedef std::map<xstring,xstring,less<xstring>,
MyAlloc<std::pair<const
xstring,xstring> > > xmap;
Note: In older printings MyAlloc was named SpecialAlloc.
Page 728, Section 15.2
In Table 15.1, the second row has to be as follows:
a.construct(p,val) | Initializes the element to which p refers with val
Page 747, Index
Insert:
Note: Page numbers in bold indicate the location of the definition of the
item. Page numbers in the normal type face are other pages of interest. If
the entry appears in source code the page numbers are in the italic type
face.
Page 7: s/International Standards Organization/International Organization for Standardization/
Page 19: s/p did not refer to an object of type Cabriolet/cp did not refer to an object of type Cabriolet/
Page 20: s/It may be but is not required to reinterpret bits/It may reinterpret bits, but it is not required to do so/
Page 29: s/The C-string, returned by what, is/The C-string returned by what is/
Page 29: s/due to a bad_alloc exception,/when a bad_alloc exception is thrown/
Page 29: s/The specification of the lifetime/The lifetime/
Page 30: s/Deriving Standard Exception Classes/Deriving from Standard Exception Classes/
Page 35: s/void foo {/void foo() {/
Page 36: s/void foo {/void foo() {/
Page 44: s/This might result in a memory leak if, for example,/This will result in a memory leak if/
Page 45: s/ClassB (ClassA val1, ClassA val2)/ClassB (const ClassA& val1, const ClassA& val2)/
Page 60: s/static
T min() throw() {/static
int min() throw() {/
Page 60: s/static T max() throw()
{/static int max() throw()
{/
Page 81: s/in Chapter 11)./in Chapter 11./
Page 90: s/set container for/container for/
Page 99: s/is in NOT/is NOT in/
Page 99: s/things are getting more complicated/things get more complicated/
Page 140: s/detailled/detailed/
Page 150: s/Table 6.2: Constructors and Destructors of Vectors/Table 6.2: Constructors and Destructor of Vectors/
Page 151: in Table 6.3: s/capacity()/c.capacity()/
Page 151: in Table 6.3: s/reserve()/c.reserve(num)/
Page 153: s/However, for vectors they are often ordinary pointers./However, for vectors the iterators returned by begin() and end() are often ordinary pointers./
Page 156: s/erase() and clear/erase() and clear()/
Page 158, Table 6.8: s/m/c/ (four times)
Page 176, Footnote 17: s/shortest path to an element/shortest path to a leaf/
Page 191: s/comparision/comparison/ (twice)
Page 230: s/pair <const key-type, value-type>/pair <const key-type, mapped-type>/
Page 238: s/make_pair(x,T())/make_pair(key,T())/
Page 252: in Table 7.1: s/vector,deque/vector,deque,/
Page 313: s/In principal/In principle/
Page 322: s/You can pass a function or function objects that specify/You can pass a function or function object that specifies/ (twice)
Page 326:s/elements of associative algorithms/elements of associative containers/
Page 344: s/find()/find_if()/ (twice)
Page 345: s/searches for three consecutive elements/searches for four consecutive elements/
Page 385: s/print element with consecutive/print elements with consecutive/
Page 385: s/print element without consecutive duplicates/print elements without consecutive entries/
Page 436: s/internally by the queue/internally by the stack/
Page 446: s/front() and back() return the next element/front() and back() return the element/
Page 474: s/searches the first occurrence/searches for the first occurrence/
Page 482, Table 11.2: s/size_type num/size_type num/ (just the font)
Page 493: s/arbitray character/arbitrary character/
Page 494: s/the value that is searched./the value that is searched for./
Page 509: s/Note that cstr may not be/Note that cstr must not be/
Page 517: s/Both forms return *this./The first form returns *this./
Page 525: s/strm.good()/strm.good()/ (just the font, twice)
Page 585: s/Section 14/Chapter 14/
Page 593: s/ostream and wstream/ostream and wostream/
Page 602: s/an exceptions is thrown/an exception is thrown/
Page 608 and 609: s/read(s) ... characters in the/read(s) ... characters into the/ (three times)
Page 622, Table 13.20: swap the meaning of dec and hex
Page 638: s/Section 3, page 683/Section 13.14.2, page 683/
Page 686: s/just 1 byte for locales, where/just 1 byte for locales where/