Lesson 19: History and Compatibility

Lesson 0019 — A Tour of C++, Chapter 19 (§19.1–§19.5)

C++ was designed to provide Simula's facilities for program organization together with C's efficiency and flexibility for systems programming. Simula was the initial source of C++'s abstraction mechanisms — the notion of class (with derived classes and virtual functions) was borrowed from it; templates and exceptions came later, with different sources of inspiration. This final technical chapter looks backward: the history of the language (timeline, early years, the standards process, style, use, and the model), the evolution of features and library components across C++11/14/17/20, what has been removed or deprecated, and the relationship with C. The thread running through it: the standard defines what works; the Core Guidelines define what is good use — and they are different things.

Why it matters: every feature you have studied in Lessons 1–18 arrived in some specific standard, for a reason rooted in real user problems — the language is problem-driven, not imitative. Knowing the timeline explains why things are the way they are (e.g., the 13-year gap that produced C++11, the "train model" that produced C++14/17/20 on schedule). Knowing what was removed tells you what not to write (auto_ptr, naked register, throw specifications), and the C-compatibility sections give the concrete rules for porting and for mixed C/C++ systems (extern "C", no implicit void* conversion). This is the chapter that turns your feature knowledge into judgment about the language itself.

19.1 History

Bjarne Stroustrup invented C++, wrote its early definitions, and produced its first implementation; he chose and formulated the design criteria, designed its major language features, developed or helped to develop many of the early libraries, and for 25 years was responsible for the processing of extension proposals in the standards committee. The evolution of C++ was always in the context of its use: he spent a lot of time listening to users, seeking out the opinions of experienced programmers, and writing code. His colleagues at AT&T Bell Laboratories were essential for the growth of C++ during its first decade.

19.1.1 Timeline

The work that led to C++ started in the fall of 1979 under the name "C with Classes." Here is a simplified timeline:

Year Event
1979 Work on "C with Classes" started: classes and derived classes, public/private access control, constructors and destructors, function declarations with argument checking. The first library supported non-preemptive concurrent tasks and random number generators.
1984 Renamed to C++. By then it had virtual functions, function and operator overloading, references, and the I/O stream and complex number libraries.
1985 First commercial release (October 14); The C++ Programming Language ("TC++PL") published.
1989 The Annotated C++ Reference Manual ("the ARM").
1991 TC++PL 2nd ed. — generic programming with templates and error handling based on exceptions, including the RAII idiom.
1997 TC++PL 3rd ed. — ISO C++: namespaces, dynamic_cast, template refinements; the STL framework of generic containers and algorithms joined the standard library.
1998 ISO C++98 standard.
2002 Work on a revised standard, colloquially named C++0x, started.
2003 A "bug fix" revision (C++03).
2011 ISO C++11: uniform initialization, move semantics, auto, range-for, variadic templates, lambdas, type aliases, a memory model suitable for concurrency — plus threads, locks, regular expressions, hash tables (unordered_map), and unique_ptr/shared_ptr in the library.
2013 First complete C++11 implementations; TC++PL 4th ed.
2014 ISO C++14: variable templates, digit separators, generic lambdas, and a few library improvements.
2015 The C++ Core Guidelines project started.
2017 ISO C++17: order-of-evaluation guarantees, structured bindings, fold expressions, a file system library, parallel algorithms, variant and optional.
2020 ISO C++20: modules, concepts, coroutines, ranges, printf()-style formatting, calendars, and many minor features.

During development, C++11 was known as C++0x — as is not uncommon in large projects, they were overly optimistic about the completion date; towards the end they joked that the 'x' in C++0x was hexadecimal, so that C++0x became C++0B. On the other hand, the committee shipped C++14, C++17, and C++20 on time, as did the major compiler providers.

19.1.2 The Early Years

Stroustrup originally designed and implemented the language because he wanted to distribute the services of a UNIX kernel across multiprocessors and local-area networks (what are now known as multicores and clusters). For that, he needed to precisely specify parts of a system and how they communicated: Simula would have been ideal, except for performance considerations; C would have been ideal for dealing directly with hardware and providing high-performance concurrent programming, except for its weak support for modularity and type checking. The result of adding Simula-style classes to C — "C with Classes" — was used for major projects in which its facilities for writing programs that use minimal resources were essential.

The name C++ (pronounced "see plus plus") was coined by Rick Mascitti in the summer of 1983; "++" is the C increment operator, signifying the evolutionary nature of the changes from C. The slightly shorter name "C+" is a syntax error. C++ was designed primarily so that Stroustrup and his friends would not have to program in assembler, C, or various then-fashionable high-level languages; its main purpose was to make writing good programs easier and more pleasant for the individual programmer. In the early years there was no C++ paper design — design, documentation, and implementation went on simultaneously — and no "C++ design committee": throughout, C++ evolved to cope with problems encountered by users.

The very first design included function declarations with argument type checking and implicit conversions, classes with the public/private distinction between interface and implementation, derived classes, and constructors and destructors. In retrospect, Stroustrup considers the introduction of constructors and destructors the most significant step — here is the root of C++'s strategies for resource management (causing a demand for exceptions) and the key to many techniques for making user code short and clear. Destructors were new in C++; no other language at the time supported multiple constructors capable of executing general code. By the October 1985 commercial release, C++ had gained inlining, consts, function overloading, references, operator overloading, and virtual functions — of these, support for run-time polymorphism in the form of virtual functions was by far the most controversial (systems programmers tended to view indirect function calls with suspicion, and doubted virtual functions could be fast enough for systems code). Early documents described C++ as "a general-purpose programming language that is a better C, supports data abstraction, and supports object-oriented programming" — notably, not "an object-oriented programming language." In the second half of the 1980s the most important additions were templates and exception handling, both considered experimental when the standards effort started; in designing templates, Stroustrup was forced to choose between flexibility, efficiency, and early type checking — he chose the first two, a choice he still considers correct. He also generalized inheritance to support multiple base classes (multiple inheritance of abstract classes — "interfaces" — is now universal in statically typed OO languages). The most important innovation in the 1998 standard library was the STL — a framework of algorithms and containers, the work of Alex Stepanov (with Dave Musser, Meng Lee, and others), based on more than a decade's work on generic programming. It was Stroustrup's deliberate policy to have the evolution of C++ "problem driven" rather than imitative: the determining influences always came from the applications he encountered.

19.1.3 The ISO C++ Standards

During 1987 it became clear that formal standardization of C++ was inevitable. AT&T Bell Labs made a major contribution by allowing Stroustrup to share drafts of revised versions of the C++ reference manual with implementers and users — about a hundred individuals from dozens of organizations read and commented on what became the base document for the ANSI C++ standardization effort (their names are in the ARM). The C++11 standard is the work of the members of WG21 (ISO SC22/WG21, now about 350 members). C++11, known for years as C++0x, was ratified by a 21-0 national vote in August 2011. One reason for the long gap between standards: most committee members were under the mistaken impression that ISO rules required a "waiting period" after a standard before starting new work — serious work on new features did not start until 2002. Other reasons: the language grew by about 30% in pages of standards text and the standard library by about 100%, and the work had to take great care not to compromise older code through incompatible changes. The overall aims for the C++11 effort were to make C++ a better language for systems programming and library building, and to make C++ easier to teach and learn. A major effort made concurrent systems programming type-safe and portable: a memory model (§18.1) and support for lock-free programming (Hans Boehm, Brian McKnight, and others), and on top of that the threads library.

After C++11 there was wide agreement that 13 years between standards were far too many. Herb Sutter proposed the "train model": shipping on time at fixed intervals. Stroustrup argued strongly for a short interval to minimize the chance of delays from someone insisting on "just one more essential feature." They agreed on an ambitious 3-year schedule, alternating between minor and major releases:

Dangers for such a large and diverse committee include "design by committee," feature bloat, lack of consistent style, and short-sighted decisions — avoiding complexity creeping in from "minor useful features" and fashion is very hard.

19.1.4 Standards and Style

A standard says what will work, and how. It does not say what constitutes good and effective use. There are significant differences between understanding the technical details of language features and using them effectively in combination with other features, libraries, and tools to produce better software — by "better" Stroustrup means "more maintainable, less error-prone, and faster." We need to develop, popularize, and support coherent programming styles, and to support the evolution of older code to these more modern styles. It is extremely difficult to make large groups of programmers depart from something that works for something better — there are still people who see C++ as a few minor additions to C, and people who enthusiastically overuse novel facilities (e.g., programmers convinced that only code using massive amounts of template metaprogramming is true C++). What is Modern C++? In 2015, Stroustrup set out to answer this question by developing a set of coding guidelines supported by articulated rationales; together with people from Microsoft, Red Hat, and Facebook, he started the C++ Core Guidelines project — an ambitious project aiming at complete type-safety and complete resource-safety as a base for simpler, faster, safer, and more maintainable code, backed up with static analysis tools and a tiny support library.

19.1.5 C++ Use

C++ is now a very widely used programming language. Its user population grew from one in 1979 to about 400,000 in 1991 — the number of users doubled about every 7.5 months for more than a decade. The growth rate slowed after that, but there were about 4.5 million C++ programmers in 2018 and maybe a million more in 2022. Much of that growth happened after 2005, when the exponential explosion of processor speed stopped so that language performance grew in importance. This growth was achieved without formal marketing or an organized user community. C++ is primarily an industrial language — more prominent in industry than in education or programming language research — used where problems require C++'s combination of the ability to use hardware effectively and to manage complexity: microelectronics, Web applications and infrastructure, operating systems, financial, medical, automobile, aerospace, high-energy physics, biology, energy production, machine learning, video games, graphics, animation, virtual reality, and much more.

19.1.6 The C++ Model

The C++ language can be summarized as a set of mutually supportive facilities:

The standard-library components add further essential support for these high-level aims.

19.2 C++ Feature Evolution

The language features and standard-library components added for C++11, C++14, C++17, and C++20. A language feature is not meant to be used in isolation — most features that are new in C++11 make no sense in isolation from the framework provided by older features (advice 3: don't focus on language features in isolation when learning C++).

19.2.1–19.2.4 Language Features

Std Language Feature
C++11 Uniform and general initialization using {} -lists; type deduction from initializer (auto); prevention of narrowing; generalized and guaranteed constant expressions (constexpr); range-for; nullptr; scoped and strongly typed enum class; static_assert; language mapping of {} -list to std::initializer_list; rvalue references enabling move semantics; lambdas; variadic templates; type and template aliases; Unicode characters; long long; alignment controls (alignas/alignof); decltype; raw string literals; suffix return type syntax; attributes ([[carries_dependency]], [[noreturn]]); noexcept specifier and operator; C99 features; __func__; inline namespaces; delegating constructors; in-class member initializers; control of defaults (default/delete); explicit conversion operators; user-defined literals; extern templates; default template arguments for function templates; inheriting constructors; override controls (override, final); a simpler and more general SFINAE rule; memory model; thread-local storage (thread_local)
C++14 Function return-type deduction; improved constexpr functions (e.g., for-loops allowed); variable templates; binary literals; digit separators; generic lambdas; more general lambda capture; [[deprecated]] attribute
C++17 Guaranteed copy elision; dynamic allocation of over-aligned types; stricter order of evaluation; UTF-8 literals (u8); hexadecimal floating-point literals; fold expressions; generic value template arguments; class template argument type deduction (CTAD); compile-time if (if constexpr); selection statements with initializers; constexpr lambdas; inline variables; structured bindings; [[fallthrough]], [[nodiscard]], [[maybe_unused]]; std::byte; initialization of an enum by a value of its underlying type
C++20 Modules; concepts; coroutines; designated initializers; the "spaceship operator" <=> (three-way comparison); [this] capture of the current object by value; [[no_unique_address]], [[likely]], [[unlikely]]; more facilities allowed in constexpr functions (including new, union, try-catch, dynamic_cast, typeid); consteval functions guaranteeing compile-time evaluation; constinit variables; using scoped enums

19.2.5–19.2.8 Standard-Library Components

The additions come in two forms: new components (such as the regular expression matching library) and improvements to C++98 components (such as move constructors for containers).

Std Library Component
C++11 initializer_list constructors for containers; move semantics for containers; forward_list; hash containers (unordered_map and friends); resource-management pointers (unique_ptr, shared_ptr, weak_ptr); concurrency support (thread, mutexes and locks, condition variables); higher-level concurrency (future, promise, async()); tuple; regular expressions (regex); random numbers (distributions and engines); integer type names (int16_t, uint32_t, int_fast64_t); array; copying and rethrowing exceptions; error reporting using error codes (system_error); emplace() operations; wide use of constexpr functions; systematic use of noexcept; improved function adaptors (function and bind()); string to numeric value conversions; scoped allocators; type traits (is_integral, is_base_of); time utilities (duration, time_point); compile-time rational arithmetic (ratio); quick_exit; more algorithms (move(), copy_if(), is_sorted()); garbage collection API (later deprecated); low-level concurrency support (atomics)
C++14 shared_mutex and shared_lock; user-defined literals; tuple addressing by type; associative container heterogeneous lookup
C++17 File system; parallel algorithms; mathematical special functions; string_view; any; variant; optional; invoke() (a way of invoking anything callable for a given set of arguments); elementary string conversions (to_chars(), from_chars()); polymorphic allocator; scoped_lock
C++20 Ranges, views, and pipelines; printf()-style formatting (format(), vformat()); calendars and time zones; span; source_location; mathematical constants (pi, ln10e); many extensions to atomics; ways of waiting for a number of threads (barrier, latch); feature test macros; bit_cast<>; bit operations; more constexpr functions; many uses of <=> in the library

19.2.9 Removed and Deprecated Features

There are billions of lines of C++ "out there," and nobody knows exactly what features are in critical use; the ISO committee removes older features only reluctantly and after years of warning. By deprecating a feature, the committee expresses the wish that the feature will go away — a deprecation is a strong hint to avoid the feature, but it may disappear only in the future. Compilers are likely to issue warnings for uses of deprecated features; however, deprecated features tend to remain supported "forever" for reasons of compatibility, and even removed features tend to live on in implementations because of user pressure.

19.3 C/C++ Compatibility

With minor exceptions, C++ is a superset of C (meaning C11). Most differences stem from C++'s greater emphasis on type checking. Well-written C programs tend to be C++ programs as well — for example, every example in K&R2 is C++. A compiler can diagnose every difference between C++ and C; the C11/C++20 incompatibilities are listed in Appendix C of the standard.

19.3.1 C and C++ Are Siblings

Classic C (K&R C plus enumerations and struct assignment) has two main descendants: ISO C and ISO C++. Over the years these languages have evolved at different paces and in different directions — each provides support for traditional C-style programming in slightly different ways, and the resulting incompatibilities can make life miserable for people who use both languages, for people who write in one language using libraries implemented in the other, and for implementers of libraries and tools for both. ISO C and ISO C++ emerge as the two major descendants of K&R C, and as siblings: each carries the key aspects of Classic C, and neither is 100% compatible with it. (There was a C++03, not listed because it was a bug-fix release; similarly C17 is a bug-fix release to C11.) Note that differences between C and C++ are not necessarily the result of changes made in C++ — in several cases the incompatibilities arise from features adopted incompatibly into C long after they were common in C++ (e.g., the ability to assign a T* to a void*, and the linkage of global consts).

19.3.2 Compatibility Problems

There are many minor incompatibilities between C and C++; all can cause problems, but in the context of C++ all can be coped with — if nothing else, C code fragments can be compiled as C and linked to using the extern "C" mechanism. The major problems for converting a C program to C++ are likely to be:

19.3.2.1 Style Problems

Naturally, a C program is written in a C style: widespread use of pointers and arrays, and probably many macros. These facilities are hard to use reliably in a large program; resource management and error handling are often ad hoc, incompletely documented and adhered to. A simple line-for-line conversion of a C program into a C++ program yields a program that is often a bit better checked — Stroustrup has never converted a C program into C++ without finding some bugs — but the fundamental structure is unchanged, and so are the fundamental sources of errors. The advice for conversion:

19.3.2.2 void*

In C, a void* may be used as the right-hand operand of an assignment to or initialization of a variable of any pointer type; in C++ it may not:

void f(int n) {
    int* p = malloc(n*sizeof(int));   // not C++; in C++, allocate using "new"
    // ...
}

This is probably the single most difficult incompatibility to deal with. Note that the implicit conversion of a void* to a different pointer type is not in general harmless:

char ch;
void* pv = &ch;
int* pi = pv;    // not C++
*pi = 666;       // overwrite ch and other bytes near ch

In both languages, cast the result of malloc() to the right type. If you use only C++, avoid malloc().

19.3.2.3 Linkage

C and C++ can be (and often are) implemented to use different linkage conventions. The most basic reason is C++'s greater emphasis on type checking; a practical reason is that C++ supports overloading, so there can be two global functions called open() — this has to be reflected in the way the linker works. To give a C++ function C linkage (so it can be called from a C program fragment) or to allow a C function to be called from a C++ program fragment, declare it extern "C":

extern "C" double sqrt(double);

Now sqrt(double) can be called from a C or a C++ code fragment. Only one function of a given name in a scope can have C linkage (because C doesn't allow function overloading). A linkage specification does not affect type checking — the C++ rules for function calls and argument checking still apply to a function declared extern "C".

19.4 Bibliography

The chapter closes with a full bibliography of the sources referenced throughout the book — the ISO standards documents ([C++,1998] through [C++,2020]), the C standards, Stroustrup's HOPL history papers ([Stroustrup,1993], [Stroustrup,2007], [Stroustrup,2020]), The Design and Evolution of C++ ("D&E") [Stroustrup,1994], the K&R C book [Kernighan,1978], the C++ Core Guidelines [Stroustrup,2015], and the WG21 document archive. Most of the documents produced as part of the ISO C++ standards effort are available online [WG21].

19.5 Advice

Here is a summary of the guidance from this chapter. All 19 items, with the section where each is introduced. The C++ Core Guidelines link each item to its recommended practice.

# Guideline §
1 The ISO C++ standard [C++,2020] defines C++. 19.1
2 When choosing a style for a new project or when modernizing a code base, rely on the C++ Core Guidelines. 19.1.4
3 When learning C++, don't focus on language features in isolation. 19.2.1
4 Don't get stuck with decades-old language-feature sets and design techniques. 19.1.4
5 Before using a new feature in production code, try it out by writing small programs to test the standards conformance and performance of the implementations you plan to use. 19.1.3
6 For learning C++, use the most up-to-date and complete implementation of Standard C++ that you can get access to. 19.1.3
7 The common subset of C and C++ is not the best initial subset of C++ to learn. 19.3.2.1
8 Avoid casts. 19.3.2.1
9 Prefer named casts, such as static_cast, over C-style casts. 5.2.3
10 When converting a C program to C++, rename variables that are C++ keywords. 19.3.2
11 For portability and type safety, if you must use C, write in the common subset of C and C++. 19.3.2.1
12 When converting a C program to C++, cast the result of malloc() to the proper type or change all uses of malloc() to uses of new. 19.3.2.2
13 When converting from malloc() and free() to new and delete, consider using vector, push_back(), and reserve() instead of realloc(). 19.3.2.1
14 In C++, there are no implicit conversions from ints to enumerations; use explicit type conversion where necessary.
15 For each standard C header <X.h> that places names in the global namespace, the header <cX> places the names in namespace std.
16 Use extern "C" when declaring C functions. 19.3.2.3
17 Prefer string over C-style strings (direct manipulation of zero-terminated arrays of char).
18 Prefer iostreams over stdio.
19 Prefer containers (e.g., vector) over built-in arrays.

Retrieval Quiz

Origins and design goals

What two languages is C++ a synthesis of, and what was the design process like?

Timeline

What happened in 1979, 1984, 1985, 1998, and 2020?

The early years

What did Stroustrup consider most significant, and which feature was most controversial?

The standards process

Why the 13-year gap, and what is the 'train model'?

Standards vs style

What does a standard NOT tell you, and what project addresses that?

C++ use and the model

What are the pillars of the C++ model, and how big is the user base?

Language feature evolution

Which standard introduced auto/lambdas/move, generic lambdas, CTAD/if constexpr, and concepts/coroutines?

Library component evolution

Which standard added threads/regex/unordered_map, shared_mutex, filesystem/variant/optional, and ranges/format/span?

Removed and deprecated

What replaces auto_ptr, throw specifications, and register?

C and C++ compatibility

Why are C and C++ called siblings, and what are the major conversion problems?

Conversion style

What replaces malloc, void* casts, C loops, and C-style strings in C++?

Linkage and headers

What does extern "C" do, and how do <cX> headers differ from <X.h>?


Notes

Origins :-

Simula classes, derived classes, virtual functions | C efficiency, flexibility for systems programming | templates/exceptions came later

motivation distribute UNIX kernel services across multicores/clusters | no paper design design, docs, implementation together | problem-driven, not imitative

name C++ (Rick Mascitti 1983, '++' = C increment) | 'C+' is a syntax error

most significant constructors/destructors (root of RAII) | most controversial virtual functions

STL Alex Stepanov, generic containers+algorithms, most important 1998 library innovation

Timeline :-

1979 C with Classes 1984 renamed C++ 1985 commercial release + TC++PL 1989 ARM 1998 ISO C++98 2011 C++11 (21-0) 2014 C++14 2017 C++17 2020 C++20 (79-0, 22-0)

C++0x dev name for C++11 joke 'x' hexadecimal, C++0B | 14/17/20 shipped on time (train model)

Standards :-

13-year gap mistaken 'waiting period' belief (work restarted 2002) + language grew ~30%, library ~100% in pages

train model Herb Sutter; fixed 3-year schedule, alternate minor/major

C++14 minor, 'completing C++11' | C++17 meant major, at best medium | C++20 as major as C++11

aims of C++11 better systems programming + easier to teach/learn | memory model + threads (Boehm, McKnight)

standard what works v/s Core Guidelines (2015, Microsoft/Red Hat/Facebook) type- + resource-safety

The model :-

8 pillars static type system | value/reference semantics | RAII | OOP | generics | compile-time programming | direct hardware access | library concurrency

users 1 (1979) → 400k (1991, doubling every ~7.5 months) → 4.5M (2018) → ~5.5M (2022) | industrial language, no marketing

Evolution :-

C++11 lang {} -init, auto, constexpr, range-for, nullptr, enum class, static_assert, rvalue refs/move, lambdas, variadic templates, aliases, noexcept, memory model, thread_local

C++14 return-type deduction, better constexpr, variable templates, binary literals, digit separators, generic lambdas, [[deprecated]]

C++17 guaranteed copy elision, CTAD, if constexpr, structured bindings, fold expressions, constexpr lambdas, inline variables, std::byte, [[nodiscard]]

C++20 modules, concepts, coroutines, <=>, designated initializers, consteval, constinit, [*this] capture, [[likely]]

lib C++11 threads/regex/unordered_map/smart pointers/atomic/future | C++14 shared_mutex | C++17 filesystem/variant/optional/string_view/parallel algos | C++20 ranges/format/span/calendars/barrier/latch/bit_cast

removed auto_ptr unique_ptr | throw specs noexcept | register, trigraphs, export | string literal → char* ; deprecated implicit *this capture, [a,b] subscript, strstream

C compatibility :-

C++ superset of C11 (minor exceptions) | Classic C ISO C + ISO C++ siblings | every K&R2 example is C++

4 conversion problems style | void* → T* implicit | keywords as identifiers | linkage

style no malloc (new, vector for realloc) | no void*/unions/casts (named casts) | span for sequences | range-for | nullptr | string/array/vector over C strings | macros → const/constexpr/enum/inline/templates/namespaces

extern "C" C linkage, callable from both | one C-linkage name per scope | × type checking unaffected | <cX> = std namespace v/s <X.h> = global


Primary source: Stroustrup, B. (2022). A Tour of C++, 3rd ed., Chapter 19: "History and Compatibility." Addison-Wesley.
Reference: Chapter 1–12 Quick Reference & Glossary — keep it beside you while you study.
Recommended supplement: the C++ Core Guidelines, Stroustrup's HOPL papers, and the WG21 document archive.

Questions? Ask your agent — your teacher — about anything unclear: why the "waiting period" myth delayed C++11, what happened to export, or when extern "C" is actually needed. Follow-ups are expected, not optional.

Chapters

  1. Lesson 1: The Basics (Ch. 1)
  2. Lesson 2: User-Defined Types (Ch. 2)
  3. Lesson 3: Separate Compilation (Ch. 3)
  4. Lesson 4: Error Handling (Ch. 4)
  5. Lesson 5: Classes (Ch. 5)
  6. Lesson 6: Essential Operations (Ch. 6)
  7. Lesson 7: Templates (Ch. 7)
  8. Lesson 8: Concepts and Generic Programming (Ch. 8)
  9. Lesson 9: Library Overview (Ch. 9)
  10. Lesson 10: Strings and Regular Expressions (Ch. 10)
  11. Lesson 11: Input and Output (Ch. 11)
  12. Lesson 12: Containers (Ch. 12)
  13. Lesson 13: Algorithms (Ch. 13)
  14. Lesson 14: Ranges (Ch. 14)
  15. Lesson 15: Pointers and Containers (Ch. 15)
  16. Lesson 16: Utilities (Ch. 16)
  17. Lesson 17: Numerics (Ch. 17)
  18. Lesson 18: Concurrency (Ch. 18)
  19. Lesson 19: History and Compatibility (Ch. 19 — this lesson)
← Course Dashboard ← Ch. 18: Concurrency Quick Reference →