Errata

Learning Modern C++ for Finance

Errata for Learning Modern C++ for Finance

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
Printed, O'Reilly learning platform
Page xix (acknowledgments in the preface)
3rd full paragraph

"C++23" and "C++26" got changed to "C23" and "C26", plus both are in fixed-width font. These should read as "C++23" and "C++26" and should be in regular font.

2025.06.24: Edited in GitLab branch dh_errata_july_2025: Changed "C++23" and "C++26" (re mdspan and BLAS interface) to {cpp}23 and {cpp}26 respectively, so that these render properly. They were rendered as `C23` and `C26` when published.

Verified in pdf.

Daniel Hanson
 
Dec 04, 2024  Jul 18, 2025
Page page 256, also page 258
in the code line "double t1 = act365_(settle_date(), d1);"

I think that a function name is missing, so the line should read instead:
"double t1 = act365_.year_fraction(settle_date(), d1);"
I would also think that a similar expression for t2 should also use act365_ (instead of act_365()) - for more consistency.

Note from the Author or Editor:
#2
Good catch, thanks very much.

The code line:
`double t1 = act365_(settle_date(), d1);`

should actually be:
`double t1 = act_365().year_fraction(settle_date(), date_01);`

as I removed the functor per recommendation from a technical reviewer (more expressive when it spells out what it does), so the error in the book would fail to compile.

2025.06.24: In dh_errata_july_2025 branch: Changed code in YieldCurve::discount_factor(.) example from

`double t1 = act365_(settle_date(), d1);`

to

`double t1 = act_365().year_fraction(settle_date(), date_01);`

as the functor was removed in favor of the year_fraction(.) member function.

**Note: Not complete per pdf -- replace date_01 with d1**

Andrey Gorbachev  Apr 29, 2025  Jul 18, 2025
Printed
Page pp 56-57
last line on p 56, first line on p 57

#14

The line says:

"\frac{2}{3} \lt \frac{4}{6}, because 4 > 2"

This line should be replaced, because in the code, the fraction is simplified at construction.

Instead, replace it with

"\frac{2}{3} \lt \frac{3}{10}, because 3 > 2"

Of course, do not include the quotation marks; I used them here to indicate what should be removed and what should be used to replace the 1st line.

I found it in the print version, but it is also in the other formats.


2025.06.24: Updated in dh_errata_july_2025...

Edit ch02.asciidoc: Line 1104 changed to:

$\frac{2}{3} 2

Now comparing 2/3 and 3/10 with lexicographic comparison (which shows this method fails, as desired).

Note: Verified fixed in pdf generated from branch.

Daniel Hanson
 
Jun 06, 2025  Jul 18, 2025
Page 30
3rd code example

Where is integ_scens defined? (is it supposed to be corr_scens?)

Note from the Author or Editor:
#12

Confirmed, but this is actually on p 310 in Ch 8.

The code block:

```
for (unsigned j = 1; j < integ_scens.cols(); ++j)
{
for (unsigned i = 0; i < integ_scens.rows(); ++i)
{
integ_scens(i, j) = gen_price(integ_scens(i, j - 1), cov_basket(i, i),
corr_norms(i, j - 1));
}
}

```
should be replaced by:

```
for (unsigned j = 1; j < corr_scens.cols(); ++j)
{
for (unsigned i = 0; i < corr_scens.rows(); ++i)
{
corr_scens(i, j) = gen_price(corr_scens(i, j - 1),
cov_basket(i, i), corr_scens(i, j));
}
}

```

2025.06.24: Corrected in dh_errata_july_2025 branch:
Edit ch08.asciidoc: Code in lines 1887-1814 has been changed to:

for (unsigned j = 1; j < corr_scens.cols(); ++j)
{
for (unsigned i = 0; i < corr_scens.rows(); ++i)
{
corr_scens(i, j) = gen_price(corr_scens(i, j - 1),
cov_basket(i, i), corr_scens(i, j));
}
}

The corr_scens(.) previously used an incorrect function name, integ_scens(.).

**Note: The code has been fixed, but the spacing needs to be adjusted (replace tabs with 4 spaces)** Follow-up: This has been fixed and checked.

Andrey Gorbachev  May 21, 2025  Jul 18, 2025
Page 79
second line

I think that constructor meant to be a move constructor (and not a copy constructor). So && instead of &.

Note from the Author or Editor:
#4

The sample code line
`OptionInfo(OptionInfo& rhs) = delete;`

requires an additional ampersand:
`OptionInfo(OptionInfo&& rhs) = delete;`

as it is a move constructor.

As an aside, these lines were not in the sample code and should be included (author's responsibility -- on GitHub)

2025.06.24: Corrected in dh_errata_july_2025:

Edit ch03.asciidoc:
The move constructor

`OptionInfo(OptionInfo& rhs) = delete;`

requires an additional ampersand

`OptionInfo(OptionInfo&& rhs) = delete;`

This change has been made.

Note: verified in pdf generated from branch

Andrey Gorbachev  May 08, 2025  Jul 18, 2025
Page 108
line 2 and line 9

I think that the declaration (with const references) is not compatible with the definition (with non-const values).

Note from the Author or Editor:
#5
This is confirmed. Under the class declaration in line 2, the constructor should instead be written as follows (remove the `const` and `&` from the parameter list); viz, it should be:

`MyPair(T first, T second);`

Note: Verified in pdf generated from branch

Update 2025.06.24, dh_errata_july_2025:
Edit ch04.asciidoc: Removed the const references in the constructor parameter for the class template MyPair<.>




More specifically, the code now reads correctly as follows:

// Class Declaration:
template <typename T>
export class MyPair
{
public:
MyPair(T first, T second) :a_(first), b_(second) {}
T get_min() const;

private:
T a_, b_;
};

// Class implementation:
template <typename T>
MyPair<T>::MyPair(T first, T second) :a_(first), b_(second) {}

template <typename T>
T MyPair<T>::get_min() const
{
return a_ < b_ ? a_ : b_;
}

Andrey Gorbachev  May 09, 2025  Jul 18, 2025
Page 132
code at the end of the page

I think that the norm_pdf lambda (commented as "Standard Normal pdf") does not follow the definition of N'(x) earlier on the same page.

Note from the Author or Editor:
#6

This is incorrect in the book but correct in the sample code on GitHub. The lambda function at the bottom of the page should read:

```
// N'(x): Standard Normal pdf:
auto norm_pdf = [](double x) -> double
{
using namespace std::numbers;
return (inv_sqrtpi / sqrt2) * exp(-x * x/2.0);
};

```

Corrected in dh_errata_july_2025:
Edit ch04.asciidoc: Standard Normal pdf lambda now correctly reads:

// N'(x): Standard Normal pdf:
auto norm_pdf = [](double x)
{
using namespace std::numbers;
return (inv_sqrtpi / sqrt2) * exp(-x * x/2.0);
};

The inv_sqrtpi and the square of x were missing (was only one x). This was correct in the sample code but not in the book.

**Note: spacing in updated pdf is not correct -- fix this.** Otherwise OK.

Andrey Gorbachev  May 12, 2025  Jul 18, 2025
Page 133
second code example

auto corp = corp = PayoffType::Put;

probably does not need corp twice.

Note from the Author or Editor:
#7

`auto corp = corp = PayoffType::Put;`

should be changed to

`auto corp = PayoffType::Put;`

Revised in dh_errata_july_2025 branch:

Edit ch04.asciidoc, Line 1370:

Changed (the error in)

`auto corp = corp = PayoffType::Put;`

to

`auto corp = PayoffType::Put;`

Note: Verified this is fixed in pdf generated from branch.

Andrey Gorbachev  May 12, 2025  Jul 18, 2025
Printed, PDF
Page 261
Last 1/3 of page

#15

face-value should be "face value", no hyphens

Daniel Hanson
 
Jun 25, 2025  Jul 18, 2025
Page 269
(2)

"presented" used twice.

Note from the Author or Editor:
# 3
Confirmed, in cue ball (2). Need to remove the repeated word, "presented".

Fixed in dh_errata_july_2025 branch: Edit ch07.asciidoc: Line 1996, cueball <2>, "presented" occurred twice; removed the redundancy.

Note: Verified in pdf from branch.

Andrey Gorbachev  Apr 29, 2025  Jul 18, 2025
Page 272
Second sentence

I think "face value" is mentioned twice in that statement while listing required inputs (so just a duplication).

Note from the Author or Editor:
#8

Confirmed. In the 1st full sentence on p 272,

"In constructing a `Bond` object, we need to supply the face value, dated date, first coupon date, penultimate payment date, and maturity date of the bond, along with its face value."

should be replaced by

"In constructing a `Bond` object, we need to supply the face value, dated date, first coupon date, penultimate payment date, and the maturity date of the bond."

Please note that `Bond` should be in fixed-width (code) font, noted by the backticks.

Fixed in dh_errata_july_2025 branch:
Edit ch07.asciidoc: Removed redundant mention of the face value in line 2063.

Note: Verified fixed in pdf generated from branch.

Andrey Gorbachev  May 15, 2025  Jul 18, 2025
Page 302
second code example

"// and save the results back ..." - code following that probably should assign the result back to vals_01.

Note from the Author or Editor:
#13

Confirmed:

The 2nd comment in the 2nd code example on p 302 should be changed from

`// and save the results back to the vals matrix object (MatrixXd):`

to

`// and save the results back to the vals_01 matrix object (MatrixXd):`


2024.06.24: dh_errata_july_2025 branch:

Edit ch08.asciidoc: In line 1300, the comment now correctly reads

// and save the results back to the vals_01 matrix object (MatrixXd):

It was previously just "vals", but the name was updated later elsewhere.


Note: Verified fixed in pdf generated from branch

Andrey Gorbachev  May 21, 2025  Jul 18, 2025
Page 341
towards the end of the page

project_prices_() should probably read project_underlying_prices_().

Note from the Author or Editor:
#11

Confirmed:
"At a high level, the labor is then divided between two private member functions that project the underlying prices from the initial node out to expiration (`project_prices_()`)... "

should instead read:
"At a high level, the labor is then divided between two private member functions that project the underlying prices from the initial node out to expiration (`project_underlying_prices_()`) ".

Also note that `project_underlying_prices_()` is in fixed width font, again indicated by the backticks.

2025.06.24, corrected in dh_errata_july_2025:
Edit ch09.asciidoc: Line 789: `project_prices_()` replaced by the correct function name `project_underlying_prices_()`.

Note: Verified fixed in pdf generated from branch.

Andrey Gorbachev  May 20, 2025  Jul 18, 2025
Page 342
3rd line from the bottom

// change name calculate_discounted_expected_payoffs - probably not meant to be in the final code?

Note from the Author or Editor:
#10

Confirmed: This comment line should be removed.

Just for the record, it was properly removed in the sample code on GitHub at the time of publication.

2025.06.24: Corrected in dh_errata_july_2025, but accidentally also corrected in main branch (because of GitLab glitch):
Edit ch09.asciidoc: Removed unneeded comment in code, previously in line 848:
// change name calculate_discounted_expected_payoffs_

Note: Verified fixed in pdf generated from branch

Andrey Gorbachev  May 20, 2025  Jul 18, 2025
Page 368
label 3

"Note that the export keyword is not used in the implementation unit" is duplicated.

Note from the Author or Editor:
#9

Confirmed. The first instance of "Note that the export keyword is not used in the implementation unit" should be removed. The 2nd instance, followed by a clause, should remain:

"Note that the export keyword is _not_ used in the implementation unit; it can be placed only in a module interface unit."

The word "not" remains in italics, indicated by the underscores.

Corrected in dh_errata_july_2025 branch:
Edit ch10.asciidoc:
Duplication of the sentence "Note that the `export` keyword is _not_ used in the implementation unit" in line 534 was removed.


Note: Verfied fixed in pdf generated from branch.

Andrey Gorbachev  May 20, 2025  Jul 18, 2025