Nicolai M. Josuttis: solutions in time  C++ Templates, 2nd Ed.: Errata for all Printings

C++ Templates - The Complete Guide, Second Edition

Errata for all Printings
November 20, 2017

This is the errata of the 1st printing of the book C++ Templates, 2nd Edition by David Vandevoorde, Nicolai M. Josuttis, and Douglas Gregor.
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


Errors

In general, throughout the book: 2017-09-01

We forgot to make it more clear that before C++17 you have to add a definition to a static constexpr declaration of a class member.

struct A {
  static constexpr int n = 5; // C++11/C++14: declaration, since C++17: definition
};

Before C++17, this is a declaration of n only. Only since C++17 is this also a definition.
So, before C++17 in exactly one translation unit you have to provide a corresponding definition, which we also missed in several examples:

// in one translation unit before C++17:
constexpr int A::n; // C++11/C++14: definition (since C++17: deprecated redundant declaration)

The reason, nobody saw this before the book was out is that often the definition is not necessary at all. In fact, you can always pass the member by value. Only when passing these members by reference and if the compiler doesn't optimize the call away link errors occur:

std::cout << A::n;       // OK even without definition (ostream::operator<<(int) gets A::n by value)

int inc(const int& i);   // pass by reference!
std::cout << inc(A::n);  // link error without definition and strong optimizations

3.1, page 46, basics/stacknontype.hpp: 2017-10-13

twice: s/assert(!elems.empty());/assert(!empty());/

3.3, page 49: 2017-09-20

The requirements for linkage in the first bullet list use the wrong C++ versions. The correct bullets are:

(the comments in the example code below shows it correctly) and right behind it:
    s/
class MyClass {/class Message { // OK /
and
    s/
MyClass<"hello"> x; // ERROR: string literal "hello" not allowed/Message<"hello"> x; // ERROR: string literal "hello" not allowed/

3.4, page 51, basics/stackauto.hpp: 2017-10-13

twice: s/assert(!elems.empty());/assert(!empty());/

13.1, page 216, table 13.1. 2017-10-24

The footnote text for Operator-function-id is missing. It should be:

Many operators have alternative representations. For example, operator & can equivalently be written
as operator bitand even when it denotes the unary address of operator.

16.3.2, page 342, on Full Function Template Specialization:2017-10-27

We didn't make it clear that a full function template specialiation only provides an alternative definition but not an alternative declaration. For this reason, the signature (including the return type) must match exactly:

template<typename T> auto foo();
template<> int foo<int>() { return 42; }  // ERROR
template<> auto foo<int>() { return 42; } // OK


Typos

Page 7, 1.1.3, Footnote: s/Visual Studio 20133/Visual Studio 2013/

Page 8, 1.2, Type Conversions During Type Deduction: before: int const c = 42; is missing: int i = 17;

Page 12, 2nd but last para of 1.3.2: s/by the standard library in <type_trait> (see Section D.5 on page 732)./by the standard library in <type_traits> (see Section D.4 on page 731)./

Page 14, 1.4: s/to depend from previous template parameters/to depend on previous template parameters/

Page 18, 1.5, basics/max3ref.cpp: s/ // run-time ERROR / // run-time ERROR (undefined behavior) /

Page 24, 2.1, basics/stack1.hpp top(): s/ // return copy of last element / // return copy of last element /

Page 27, 2.1.2, top: s/ // return copy of last element / // return copy of last element /

Page 29, 2.3: s/void printOn() (std::ostream& strm) const {/void printOn(std::ostream& strm) const {/

Page 30, 2.4: s/void printOn() (std::ostream& strm) const {/void printOn(std::ostream& strm) const {/

Page 36, 2.7, basics/stack3.hpp top(): s/ // return copy of last element / // return copy of last element /

Page 40, 2.9, 1st para: s/(that don’t have a default value),/(that don’t have a default value)./

Page 40, 2.9, 1st code snippet: s/Stack<int> intStack1; // stack of strings/Stack<int> intStack1; // stack of ints/

Page 41, 2.9, 1st bullet: s/Due to the definition of the int constructor, /Due to the definition of the constructor template, /

Page 48, 3.2: s/and std::transform() need a complete type/and std::transform() needs a complete type/
           
and: s/the see, what could fit,/then see, what could fit,/

Page 50, 3.3: s/In all three cases a constant character array is initialized by "hello"/In all three cases a constant character array is initialized by "hi"/

Page 56, 4.1.1: s/Thus, after printing "world" as firstArg, we calls print() with no arguments/Thus, after printing "world" as firstArg, we call print() with no arguments/

Page 61, 4.3, first code snippet: s/v.emplace("Tim", "Jovi", 1962);/v.emplace_back("Tim", "Jovi", 1962);/

Page 62, 4.4.1, mid code snippet: s/std::complex<float>(4,2) + std::complex<float>(4,2);/std::complex<float>(4,2) + std::complex<float>(4,2));/

Page 69, 5.2: twice as code comment: s/ // x is zero (or false) if T is a built-in type/ // x is zero (or false or nullptr) if T is a built-in type/

Page 87, 5.7, basics/stack9.hpp top(): s/ // return copy of last element / // return copy of last element /

Page 93, 6.1, first paragraph: s/instead of g(&&) would be called./instead of g(X&&) would be called./

Page 93, 6.1, first code snippet: s/void f(T val) {/void f(T& val) {/   and   s/g(T);/g(val);/

Page 101, 6.4, bottom: s/However, the order of the arguments is the opposite is this case:/However, the order of the arguments is the opposite in this case:/

Page 108, 7.1, code in "Passing by Value Decays": s/printV(arr); // decays to pointer so that arg has type char const*/printV(arr); // decays to pointer so that arg has type int const*/

Page 112, 7.2, code: s/passR("hi"); // OK: T deduced as int (&)[4] (also the type of arg)/passR(arr); // OK: T deduced as int (&)[4] (also the type of arg)/

Page 113 top, 7.3: code example: s/printT(s); // pass s by reference/printT(s); // pass s by value/

Page 131, 8.4: s/(match with ellipsis (...) in overload resolution (see Section C.2 on page 682)./(match with ellipsis (...) in overload resolution, see Section C.2 on page 682)./

Page 132; 8.4, real std::thread definition: s/typename = std::enable_if_t<!std::is_same_v<std::decay_t<F>,/ typename = enable_if_t<!is_same_v<decay_t<F>,/

Page 133, 8.4.1: s/decltype( (void)(t.size)(), T::size_type() )/decltype( (void)(t.size()), T::size_type() )/

Page 134, 8.5: s/that allows is to enable or disable/that allows us to enable or disable/

Page 137, 9.1.1, first bullet: s/Classes and other types are entirely placed in header files./Classes and other type declarations are entirely placed in header files./

Page 147, 9.4: line numbering wrong after "immediately followed by more than 20 other error messages:": First line be 17 instead of 16 (or all following one less)

Page 169, 11.4, basics/referror2.cpp: s/loops over 120 elements/loops over 110 elements/

Page 181, 12.1, Nontemplate Members of Class Templates, 1st para: s/a class template They are occasionally/a class template. They are occasionally/

Page 206, 12.4.4, last code block: should only have the O1 and O2 expansion (skip comma, O3(...))

Page 209, 12.4.6, close to the end, first bullet: s/the value true,./the value true./

Page 262: 14.5.1, second example: s/ // ===== t.hpp: / // ===== f.tpp: /

Page 283: 15.6.4: s/template<typename Other> X(X<U>&&); // X<U> is not a template parameter/template<typename U> X(X<U>&&); // X<U> is not a template parameter/

Page 287: 15.8.1: s/int r = f(v, 7.0); // OK: T is deduced to int through the first parameter,/int r = f(v, 7.0); // OK: T is deduced to V through the first parameter,/

Page 301, 15.10.3 code comment: s/x1 has type int/x has type int/

Page 316: 15.12.2 code example: s/S y{s1};/S y{x};/  and  s/S z(s1);/S z(x);/  and  s/but what should the type of x and y be?/but what should the type of y and z be?/

Page 420, 19.4.2, 1st para after traits/isdefaultconstructible3.hpp: s/because by default a type doesn’t have the member size_type./assuming by default a type doesn’t have a default constructor./

Page 666, A.3.1: the second: s/ //====== translation unit 1: / //====== translation unit 2: /


Home of the C++ Templates book