About C++ Crash Course

A fast-paced, thorough introduction to modern C++ written for experienced programmers. After reading C++ Crash Course, you’ll be proficient in the core language concepts, the C++ Standard Library, and the Boost Libraries.

C++ is one of the most widely used languages for real-world software. In the hands of a knowledgeable programmer, C++ can produce small, efficient, and readable code that any programmer would be proud of.

Designed for intermediate to advanced programmers, C++ Crash Course cuts through the weeds to get you straight to the core of C++17, the most modern revision of the ISO standard. Part 1 covers the core of the C++ language, where you’ll learn about everything from types and functions, to the object life cycle and expressions. Part 2 introduces you to the C++ Standard Library and Boost Libraries, where you’ll learn about all of the high-quality, fully-featured facilities available to you. You’ll cover special utility classes, data structures, and algorithms, and learn how to manipulate file systems and build high-performance programs that communicate over networks.

You’ll learn all the major features of modern C++, including:

  • Fundamental types, reference types, and user-defined types
  • The object lifecycle including storage duration, memory management, exceptions, call stacks, and the RAII paradigm
  • Compile-time polymorphism with templates and run-time polymorphism with virtual classes
  • Advanced expressions, statements, and functions
  • Smart pointers, data structures, dates and times, numerics, and probability/statistics facilities
  • Containers, iterators, strings, and algorithms
  • Streams and files, concurrency, networking, and application development

Downloading the Code

C++ Crash Course contains well over 500 code samples & nearly 100 exercises.

You can download all of them from Github.

You can clone the repository:

git clone git@github.com:JLospinoso/ccc

Or simply download the files using your browser:

So long as you have CMake, Boost, and git installed, you can then build all the examples with an out-of-source build:

cd ccc
git submodule init
git submodule update
mkdir build
cd build
cmake ..


To report an erratum, please submit an issue on Github https://github.com/JLospinoso/ccc/issues.
  • p. 31 std::byte and size_t are not "fundamental types" in the C++ standard and should have their own section labeling them as such.
  • p. 41 "The usual format specifiers for a size_t are %zd for a decimal representation or %zx for a hexadecimal representation." The correct format specifier for size_t is %zu, which is the unsigned version of %zd. This error appears consistenly throughout the remainder of the book!
  • p. 97 The C++ Standard says that thread_local variable lifetimes begin at latest upon first use by the thread. The text implies that the thread_local life time is similar to a static lifetime. You can modify Listing 4-6 by inserting the line "const auto t2_ptr = &t2;" at the very beginning of main, or at namespace scope.
  • p. 140 Listing 5-6 is misleading. This updated listing illustrates better how private members interact with inheritance.
  • p. 160 SimpleUniquePointer's parameterless constructor should not be default. It should initialize the pointer member to nullptr. Also, the move assignment operator and the destructor do not need to check if pointer equals nullptr. Deleting a nullptr is totally valid.
  • p. 353 fclose returns an int. If it's successful, fclose returns 0, otherwise EOF. (See https://en.cppreference.com/w/c/io/fclose)
  • p. 626 std::min, std::max, and std::minmax cannot accept temporary objects, since they return const references to their arguments. The min and max example has undefined behavior for this reason. The example should declare string variables and pass these instead. See this commit for one possible fix.>
  • p. 644 factorize in Listing 19-6 is not a proper integer factorization algorithm because it only retains the unique prime factors, not their powers. One possible fix is to replace std::set with std::multiset or std::vector to retain non-unique primes.


  • p. xl In Listing 4, "mannie_service" should read "make_sentient"
  • p. xliv "and the function in the Jabberwock namespace" should read "and the function in the Func namespace"
  • p. liv "the destructor cleans up file.file_pointer for you (2)" should read "...(3)"
  • p. 10 "$ g++-8 –version" shoud read "$ g++-8 --version"
  • p. 18 "hexadecimal and octal output" shoud read "hexadecimal, decimal, and octal output"
  • p. 21 "These symbols, // or /**/, tell the compiler" should read "The // symbol tells the compiler"
  • p. 33 (EPUB only) "There are 69,105 leaves in here." should read "There are 69,105 leaves here."
  • p. 41 "C type in the header" should read "C type in the C library header "
  • p. 57 Listing 2-21 is missing a semi-colon is after the definition of the struct ClockOfTheLongNow.
  • p. 62 "Whether array_5 is initialized or not..." Should read "Whether array_4 is initialized or not..."
  • p. 76 In Listing 3-7, "*(lower + 4)" and "*(upper_ptr + 4)" should read "*(lower + 3)" and "*(upper_ptr + 3)", respectively.
  • p. 78 "Each Element also contains a prefix array (5) and an operating_number pointer (6)." Should read "... and an operating_number short."
  • p. 80 "Next, you initialize another int called new_value to 200 and assign it to original(3)."
  • p. 91 "Another feature of being declared at global scope is that power_up_rat_thing" should read "Another feature of being declared at global scope is that rat_things_power".
  • p. 92 (ebook only) "Finally, you check whether waste_heat is over a threshold value of 1000 (4)." should read "...of 10000 (4)."
  • p. 96 "delete[] my_int_ptr" should be "delete[] my_int_array_ptr"
  • p. 100 "Handlers will catch a given type and any of its parents’ types." should read "...childrens' types."
  • p. 105 The Note should refer to Item 14, not Item 16 of Effective Modern C++ by Scott Meyers.
  • p. 110 In listing 4-16, (3) and (5) should read string.print("A") and string.print("B").
  • p. 110 "(It’s your responsibility as a user of string to check for this condition.)" should read "(It’s your responsibility as a user of SimpleString to check for this condition.)"
  • p. 111 In listing 4-18, "Constructed: " and "About to destroy: " should read "Constructed" and "About to destroy".
  • p. 112 "fn() → fn_b() → fn_c()" should read "main() → fn_b() → fn_c()"
  • p. 118 "You can use array new (1) to initialize buffer because you know" should read "You can use array new (2) to initialize buffer because you know"
  • p. 118 In Listing 4-27, "This change is lost." should read "Change lost."
  • p. 120 In listing 4-30, "strcpy_s(buffer, max_size, other.buffer);" should read "std::strncpy(buffer, other.buffer, max_size);"
  • p. 128 The copy constructor in Listing 4-38 should use braced initializers for its member initializer, as in Listing 4-35.
  • p. 130 The Move Assignment checkmark is in the wrong place: typo p.130

  • p. 137 (ebook only) The Note referring to Chapters 20 and 21 of "The C + + Programming Language" (4th Edition, by Bjarne Stroustrup) should not contain hyperlinks.
  • p. 145 In listing 5-13, "// Include Listing 5-10" should read "// Include Listing 5-10"
  • p. 147 In Listing 5-14, "Bank(Logger* logger) : logger{ logger } ()" should read "Bank(Logger* logger) : logger{ logger } {}"
  • p. 149 (ebook only) The Martha Stewart quote should read "The more you adapt, the more interesting you are."
  • p. 155 "Notice that you need to provide only a single template parameter, the return type, upon instantiation (1)(4)." should read "...upon instantiation (2)(5)."
  • p. 156 "T(2) mean(T*(3) values, size_t length) {" should read "T(2) mean(const T*(3) values, size_t length) {"
  • p. 158 In Listing 6-12, "char mean(const char* values, size_t length)" should read "size_t mean(const size_t* values, size_t length)" and "char result{};" should read "size_t result{}".
  • p. 159 "For example, if a template function’s return type is a template argument," should read "For example, if a template function’s return type is a template argument that's entirely independent of other function and template arguments,"
  • p. 160 Listing 6-15 could be improved by modifying the consumer function to take an rvalue reference.
  • p. 167 The paragraph "The concept is composed of three Boolean expressions AND-ed (&&) together: two type traits (1) (3) and a requires expression." should read as follows: "The concept is composed of a type trait (1) and a requires containing two requirement expressions (2) (3)."
  • p. 175 "element-type(param-name&)[array-length]" should read "element-type(¶m-name)[array-length]"
  • p. 175 "out_of_bounds" should read "std::out_of_range"
  • p. 187 Listing 7-2 should throw a std::overflow_error at (4).
  • p. 188 "This argument is used to member initialize the private field value." Should read "This argument is used to member initialize the public field value."
  • p. 195 Table 7-6: The description for "a ^ b" should read "Bitwise XOR"
  • p. 200 "The address refers to the address of x (1) and prints 0 (2)." should read "The print_addr function prints the address of x (1) and the value of nullptr, 0 (2)."
  • p. 203 Listing 7-14 Caption, "A refactor of Listing 7-13 using a static_cast..." should read "A refactor of Listing 7-13 using a reinterpret_cast...".
  • p. 205 "whchar_t" should read "wchar_t".
  • p. 237 "const auto x = range.begin()" should read "auto x = range.begin()".
  • p. 239 To assign a label, prepend a statement with the desired name of the label followed by a colon.
  • p. 241 "Implement a PrimeNumberRange class that can be used in a range exception to iterate over" should read "Implement a PrimeNumberRange class that can be used in a range expression to iterate over"
  • p. 251 "..., you call va_list with the va_list structure" should read "..., you call va_end with the va_list structure"
  • p. 251 "Notice that the second argument of va_args is a type." should read "Notice that the second argument of va_arg is a type."
  • p. 252 "typename...Args" should read "typename... Args"
  • p. 253 "all elements in a parameter pack called pack:" should read "all elements in a parameter pack called args:"
  • p. 258 For clarity, the term "modifiers(5)" in the Lambda Usage listing should read "specifiers(5)".
  • p. 261 In listing 9-7, "transform(translate, base_int, a, l); (5)" should read "transform(translate, base_int, a, len); (5)" and "transform(translate, base_float, b, l); (6)" should read "transform(translate, base_float, b, l); (6)"
  • p. 277 Exercise 9-1, "print("Sum: %d\n", sum);" should read "printf("Sum: %d\n", sum);"
  • p. 277 Exercise 9-3, "template <typename Fn, typename In, typename Out>" should read "template <typename Fn, typename In>"
  • p. 284 Figure 10-1, the direction of the arrows, SpeedUpdate, CarDetected, BrakeCommand, are reversed.
  • p. 289 "That’s all you have to do; assert will throw an exception if the initial speed is zero." should read "isn't zero."
  • p. 291 "Listing 10-9: A unit test encoding the requirement that the initial speed be zero" should read "that the initial sensitivity is five"
  • p. 293 In Listing 10-14, "std::except" should be "std::invalid_argument"
  • p. 302 "You can add this into the AutoBus constructor, as demonstrated in Listing 10-27" should read "You can add this into the AutoBrake constructor, as demonstrated in Listing 10-27"
  • p. 304 "single-header" should read "single_header" (to correspond with the correct subdirectory within Catch).
  • p. 311 "that share some a common theme" should read "that share a common theme"
  • p. 313 "Listing 10-38: Intentionally commenting out the collision_threshold_s" should read "Intentionally commenting out the speed_mps"
  • p. 319 Listing 10-41: Caption should read "Using Boost Test" rather than "Using Google Test"
  • p. 327 Listing 10-50: "publish(A<BrakeCommand>)" should read "publish(A<BrakeCommand>())"
  • p. 328 Table 10-2: "A<type>)()" should read "A<type>()"; "An<type>)()" should read "An<type>()"
  • p. 336 "IServiceBusMock" should read "IServiceBus mock"
  • p. 351 "ownership to son_of_aragorn. Because son_of_aragorn can" should read "ownership to son_of_arathorn. Because son_of_arathorn can"
  • p. 359 "to convert Listing 11-12 to use a shared pointer" should read "to convert Listing 11-13 to use a shared pointer"
  • p. 367 Listing 11-19: "my_alloc" should read "alloc"
  • p. 367 "and operator!= returns true (7)" should read "and operator!= returns false (7)"
  • p. 368 Exercise 11-1: Should read "Reimplement Listing 11-13 to use a ..."
  • p. 382 Table 12-6, "Convenience function for constructing a tuple" should read "Convenience function for constructing a variant"
  • p. 382 Table 12-6, "std::visit(vt, callable)" should read "std::visit(callable, vt)"
  • p. 382 Table 12-6, "std::get(vt)" should read "std::get(vt)"
  • p. 382 Table 12-6, "std::get_if(&vt)" should read "std::get_if(&vt)"
  • p. 385 (ebook version only) '+boost::gregorian::date supports periods+' should read '"boost::gregorian::date supports periods"'
  • p. 385 Table 12-8, "Returns the month portion of the date" should read "Creates a period from d to d+n_days"
  • p. 391 "store into the time_per_addition variable (6)" should read "store into the time_per_division variable (6)"
  • p. 401 "boost::converter" should read "boost::numeric::converter". This occurs in a handful of places from p. 401 to p. 403.
  • p. 404 Table 12-16, table header "Distribution" should read "Operation".
  • p. 404 The subtitle "A Partial List of Random Number Distributions" should read "A Partial List of Operations Available in <ratio>".
  • p. 409 In listing 13-1, "std::array static_array;" should read "std::array static_array{};"
  • p. 411 "You've also have" should read "You also have".
  • p. 431 "Constructs a priority_queue of Ts using ctr as its internal container and srt as its comparator object." should read "...and cmp as its comparator object."
  • p. 432 Listing 13-22 initializes the nybble 0101 incorrectly; it should read "std::bitset<4> bs(0b1010);". It would be helpful to add a note that operator[] accesses the bits such that the 0-th element is the least-significant bit.
  • p. 433 "Flips the i-th bit to zero." should read "Flips the i-th bit."
  • p. 437 "when you give the key 8 (3)" should read "when you give the key 100 (3)"
  • p. 445 "Performs braced initialization of a newly constructed ordered set" should make more explicit that the "braced initialization" occurs using the elements indicated by the ellipses.
  • p. 451 "m.emplace_hint(k, ...)" should read "m.emplace_hint(itr, ...)"
  • p. 451 "m.try_emplace(itr, ...)" should read "m.try_emplace(k, ...)"
  • p. 451 "Throws std::out_of_bounds" should read "Throws std::out_of_range"
  • p. 456 "You can remove subtrees from a ptree using the get_child method, ..." should read "You can get subtrees from a ptree using the get_child method, ..."
  • p. 460 Exercise 13-4 is a duplicate of exercise 13-1 and can be ignored. (Kindle only: "Implement a Matrix class ..." is an unnumbered exercise. After removing the duplicate exercise 13-4, this exercise would be labeled 13-6.)
  • p. 460 In Exercise 13-5, "//TODO: Adapt code from Exercise 12.1" should instead refer to "Exercise 13-1". Also, "long cached_fib_sum(size_t n) { (4)" would be preferred over "long cached_fib_sum(const size_t& n) { (4)".
  • p. 468 "operator—(int)" should read "operator--(int)"
  • p. 493 In the Summary of string Manipulation Methods section, the last sentence reads "invalidates raw pointers and iterators to v's elements ..." It should read "invalidates raw pointers and iterators to s's elements ..."
  • p. 495 The "this" in "The find_first_of function accepts a string and locates the first character in this contained in the argument." should have literal formatting.
  • p. 497 In the Summary of string Search Methods section, "pos" should read "p"
  • p. 508 There's an issue with the font in "$' for the characters before a match, $' for the characters after the match,". It should should read $` for the characters before a match, $´ for the characters after the match,".
  • p. 513 "In this table, r is a string range, and beg and end are element comparison predicates" should read "...are characters defining the range". The corresponding entry in Table 15-13 should read "Contained in the range from beg to end". The range is not half-open.
  • p. 519 "First instance of s2 in s1" should read "Last instance of s2 in s1".
  • p. 519 "In this table, s, s1, and s2 are strings; p is an element comparison predicate; rgx is a regular expression; and n is an integral value" should also mention that "fnd is a finder".
  • p. 546 "Writing Files to sdout" should read "Writing Files to stdout".
  • p. 561 Kindle Only: "last_write_time( p, [t] [ec]), which, if tect is provided," should read "...if t is provided,"
  • p. 562 Kindle Only: "anerror" should read "an error"
  • p. 571 "perform a recursive directory" should read "perform a recursive directory search"
  • p. 573 Kindle Only: "stupidmachine" should read "stupid machine"
  • p. 574 To avoid confusion, "Polynomial (or quadradic) time" should just read "Quadratic time".
  • p. 584 The subsection title "find_first" should read "find_first_of". Note that the Kindle formatting could be better here (sorry!).
  • p. 590 Within the description for search, ipt_begin1/ipt_begin2 should read fwd_begin1/fwd_begin2. Additionally, "or ipt_begin2 if no subsequence is found" should read "or fwd_end1 if no subsequence is found"
  • p. 591 "ForwardIterator search([ep], fwd_begin, fwd_end, count, value, [pred]);" should say "search_n" rather than "search"
  • p. 596 "elements of detector1 are in a moved from state" should read "elements of detectors1 are in a moved from state", and "the elements of detector2 are moved into detectors2" should read "the elements of detectors1 are moved into detectors2".
  • p. 597 "detector1"/"detector2" should say "detectors1"/"detectors2"
  • p. 600 "An old const reference" should say "An old_ref const reference" for consistency
  • p. 608 back_inserter(counts) should read back_inserter(result). See sample.cpp
  • p. 614 "If modifying, the algorithm sorts the first (rnd_middle – rnd_first) elements", should read "If modifying, the algorithm sorts the first (rnd_middle – rnd_begin) elements"
  • p. 616 "next you invoke is_sort" should read "next you invoke is_sorted".
  • p. 616 "BidirectionalIterator partition([ep], bid_begin, bid_end, pred);" should read "BidirectionalIterator stable_partition([ep], bid_begin, bid_end, pred);"
  • p. 660 "If the function object has mutable state" should read "If the function object has shared mutable state".
  • p. 702 (Kindle only) "positionalarguments" should read "positional arguments".
  • p. 705 "Listing 21-12 provides a snippet that you could append into main after Listing 21-10 to parse results into a variables_map" should read "Listing 21-12 illustrates how you can retrieve values from a variable_map."


p. xxxv: Companion Code

Foreword: An Overture to C Programmers

p. xxxix: C Constructs That Don't Work in C++

Chapter 1: Up and Running

p. 6: Wandbox

p. 6: Compiler Explorer

p. 6: Cling (Note: Not mentioned in the book, but a nice C++ REPL.)

p. 6: Visual Studio 2017 Community Edition Download

p. 10: GCC, the GNU Compiler Collection

p. 10: Clang: a C language family frontend for LLVM

p. 11: GCC mirror sites

p. 11: GnuPG

p. 12: Installing GCC: Configuration

p. 12: Installing GCC: Building

p. 12: Installing GCC: Testing

p. 12: Installing GCC

p. 12: The gcc-help mailing list archives

p. 23: Visual Studio Walkthrough: Debugging a Project (C++)

p. 25: About LLDB and Xcode

p. 25: GDB: The GNU Project Debugger

p. 25: The LLDB Debugger

p. 28: Debugging with GDB

p. 28: Stack Overflow

p. 28: CPP Subreddit

p. 28: CPP Slack

p. 29: CPPCast

p. 29: CPPReference

p. 29: CPlusPlus

p. 29: The "Draft" ISO C++ Standard (2017)

Chapter 2: Types

p. 35: The IEEE Standard for Floating-Point Arithmetic, IEEE 754.

p. 65: C++ Made Easier: Plain Old Data

Chapter 3: Reference Types

p. 86: Microsoft Security Bulletin MS01-033 - Critical (Code Red)

p. 87: C++ Core Guidelines

p. 87: East End Functions

p. 87: References

Chapter 6: Compile-time Polymorphism

p. 171: The Origin Library

Chapter 7: Expressions

p. 189: HeapAlloc

p. 189: malloc

p. 207: HSV Conversion

Chapter 10: Testing

p. 304-5, 309: Catch2

p. 310, 325, 328: Google Test/Google Mocks Documentation

p. 310: Instructions for Google C++ Testing (For Dummies), Unix Edition

p. 317: Boost Test

p. 333: HippoMocks

p. 337: FakeIt

p. 337: Trompeloeil

p. 339: Editor War

p. 339: Is TDD Dead?

Chapter 11: Smart Pointers

p. 349: Boost Smart Pointer

p. 363: Boost Intrusive

p. 387: Boost DateTime

Chapter 12: Utilities

p. 401-403: Boost Numeric Conversion

Chapter 13: Containers

p. 415: CPPReference

p. 415: CPlusPlus

p. 433: Boost Container

Chapter 15: Strings

p. 500: Boost Lexical Cast

p. 512, 515: Boost String Algorithms

Chapter 17: Filesystems

p. 551: Boost Filesystem

p. 571: The dir Command

p. 571: The ls Command

Chapter 18: Algorithms

p. 637: Boost Algorithm

p. 638: Boost Range

p. 638: Algorithmic Complexity

Chapter 19: Concurrency and Parallelism

p. 643: Integer Factorization

p. 655: Boost Lockfree

p. 662: C++ and The Perils of Double-Checked Locking

p. 662: Effective Concurrency: Know When to Use an Active Object Instead of a Mutex

Chapter 20: Network Programming with Boost Asio

Note: ARCYBER has moved to TLS so the example in Listing 20-10 will complain. You can replace this URL with any server supporting non-TLS HTTP. For example, http://asdf.com works as of June 9, 2020.

p. 665: Boost Asio

p. 667: IANA Service Name and Transport Protocol Port Number Registry

p. 677: Boost Beast

p. 677: IETF RFCs

p. 677: Boost Beast example projects

p. 684: IANA Service Name and Transport Protocol Port Number Registry

p. 685: netcat

p. 689: nmap

Chapter 21: Applications

p. 704: Boost Program Options

p. 713: Boost Python