Guidelines for Teaching C++

SG20

1 Disclaimer

This document is intended as a proof of concept to solicit feedback from others. This document is incomplete. This document undoubtedly has errors.

2 Context and Aim of This Guide

This document is intended to serve as a resource for instructors to assist in the preparation of courses on C++ in a variety of settings, including university, college, and industry environments. The main objectives of this document are as follows:

This document does not itself provide a curriculum for a single specific course, but is rather a set of guidelines that can be used to prepare curricula for a wide variety of courses that differ in focus and level of sophistication. (This said, however, some links to other documents with examples of curricula for specific courses may be included herein.)

3 Use of This Document

[NOTE: This is following the same license model as the C++ Core Guidelines.] Copying, use, modification, and creation of derivative works from this project is licensed under an MIT-style license. A copy of the license is included in the section LICENSE.

4 Contributing

All contributions to this project must be made in accordance with the license mentioned above. Contributors should familiarize themselves with the general organization of this document and learning outcomes. Some information on learning outcomes can be found in the references. The following document offers a concise introduction to learning outcomes:

5 Organization of This Document

The various concepts (i.e., ideas) to potentially be covered are partitioned into “Knowledge Areas”. A knowledge area is very broad in scope, covering a considerable range of topics. Each knowledge area, in turn, in comprised of a number of what are referred to as “knowledge units”. Knowledge units are narrower in scope than knowledge areas.

For each knowledge area, the scope of the area is first described and its constituent knowledge units are identified. Then, for each knowledge unit (within an area), learning outcomes are specified. In order to address a wide variety of courses on C++, the learning outcomes are partitioned across three main proficiency levels:

These proficiency levels target audiences with different background and learning objectives as specified in the following table: [NOTE: These definitions of proficiency levels are only a first attempt and will undoubtedly need further work.]

Proficiency Level Approximate Description
basic a relative newcomer to C++ that would like to be able to write relatively small and simple programs which rely mostly on libraries written by others
intermediate someone already familiar with rudimentary C++ that would like to be able to write more sophisticated programs/libraries with some larger or more complex components
advanced someone who is very experienced with C++ who would like to be able to better utilize the many more nuanced aspects of the language

The remainder of this document is organized as follows. The various knowledge units are listed grouped by knowledge area. In cases where a knowledge unit might be classified into more than one area, the unit is listed under the area of most direct relevance. (In the case that a unit is equally relevant to multiple areas, the decision of which to select is made by a proverbial coin toss.) The order in which knowledge areas and units are presented are not meant to imply any order of coverage in a course. The order in which items are listed is essentially arbitrary.

So, in summary, we have the following organization:

6 Knowledge Areas and Units

In the sections that follow, the various knowledge areas and knowledge units are presented. There is one section per knowledge area. For each knowledge area, a table listing the various knowledge units is provided. The ID for a knowledge unit is linked to the detailed coverage of that unit that comes later in the document. In the table, a checkmark indicates that learning outcomes exist for the specific proficiency level. A dash indicates that no learning outcomes exist for the specfic proficiency level (simply because there are not any, not because the information is missing). In the case that the information for a knowledge unit is completely missing, a “🤢” symbol is used.

[NOTE: These topics are taken mostly from the SG20 GitHub repository. They are not intended to be complete in any sense. In fact, by gathering together all topics in one place where they are easily viewed, it is hoped that missing and unbalanced items will be more obvious.]

6.1 [CM] Compilation Model

ID Unit Basic Intermediate Advanced
[🤢] Translation Units ? ? ?
[🤢] Headers ? ? ?
[🤢] Modules ? ? ?
[🤢] Name Mangling ? ? ?
[🤢] Phases of Translation ? ? ?
[🤢] Separate Compilation ? ? ?
[🤢] Linkage ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.2 [P] Preprocessor

ID Unit Basic Intermediate Advanced
[🤢] Preprocessor Metaprogramming ? ? ?
[🤢] Inclusion ? ? ?
[🤢] Macros ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.3 [B] Basics Types, Objects, Values, Expressions, Statements, and Control-Flow Constructs

ID Unit Basic Intermediate Advanced
[🤢] Constant Objects ? ? ?
[🤢] Declarations and Definitions ? ? ?
[🤢] Selection Constructs (e.g., if, ternary) ? ? ?
[🤢] Looping Constructs (e.g., for, while, etc.) ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.4 [F] Functions

ID Unit Basic Intermediate Advanced
[🤢] Calling Functions ? ? ?
[🤢] Parameter Passing (e.g., Passing By Value and Reference) ? ? ?
[func_args] Default Arguments - -
[🤢] Returning Multiple Values ? ? ?
[🤢] Overloading ? ? ?
[udl] User-Defined Literals -

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.5 [C] User-Defined Types (Classes)

ID Unit Basic Intermediate Advanced
[🤢] Special Member Functions ? ? ?
[copy_elision] Copy Elision and Implicit Moving (e.g., RVO and NRVO, etc.) -
[🤢] Types ? ? ?
[🤢] Conversions ? ? ?
[🤢] Constructors and Destructors ? ? ?
[🤢] Move/Copy Constructors and Assignment Operators ? ? ?
[🤢] Member Functions ? ? ?
[🤢] Sum Types ? ? ?
[🤢] User-Defined Literals ? ? ?
[🤢] Special Member Functions ? ? ?
[🤢] Guidelines for Special Member Functions (e.g., Rule of Five, Rule of Zero) ? ? ?
[copy] Copy Semantics -
[🤢] Moving and Copying ? ? ?
[🤢] Lambdas ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.6 [I] Inheritance and Class Hierarchies

ID Unit Basic Intermediate Advanced
[🤢] Virtual Functions ? ? ?
[🤢] Run-Time Type Information ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.7 [CT] Compile-Time Computation

ID Unit Basic Intermediate Advanced
[🤢] Constant Expressions and Constant Evaluation ? ? ?
[🤢] static_assert ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.8 [T] Generic Programming (Templates)

ID Unit Basic Intermediate Advanced
[🤢] Concepts ? ? ?
[🤢] SFINAE ? ? ?
[🤢] Template Metaprogramming ? ? ?
[🤢] Function Templates ? ? ?
[🤢] Requires Clauses ? ? ?
[req_expr] Requires Expressions -

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.9 [EH] Error Handling

ID Unit Basic Intermediate Advanced
[🤢] Classes of Errors ? ? ?
[🤢] errno ? ? ?
[🤢] Error Codes ? ? ?
[🤢] Exception Handling ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.10 [SL] Standard Library

ID Unit Basic Intermediate Advanced
[🤢] Input/Output (I/O) ? ? ?
[🤢] Containers, Iterators, and Algorithms ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.11 [EL] External (i.e., Non Standard) Libraries

ID Unit Basic Intermediate Advanced
[🤢] Graphical User Interfaces ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.12 [BLD] Building

ID Unit Basic Intermediate Advanced
[🤢] Software Build Tools ? ? ?
[🤢] Strategies for Handling Build Problems ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.13 [TD] Testing and Debugging

ID Unit Basic Intermediate Advanced
[🤢] Source-Level Debuggers ? ? ?
[🤢] Code Sanitizers ? ? ?
[🤢] Test Frameworks ? ? ?
[🤢] Debugging Strategies ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.14 [TOOL] Tooling

ID Unit Basic Intermediate Advanced
[🤢] Compiler Toolchains ? ? ?
[🤢] IDEs ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

6.15 [SD] Software Design

ID Unit Basic Intermediate Advanced
[🤢] Design by Contract ? ? ?

Note: 🤢 indicates no entry yet available

Note: The IDs and checkmarks (✓) are linked to the corresponding sections.

7 Detailed Information for Knowledge Areas and Units

7.1 Copy Elision and Implicit Moving

7.1.1 Basic Learning Outcomes

7.1.2 Intermediate Learning Outcomes

After completing this unit, the student should be able to:

7.1.3 Advanced Learning Outcomes

After completing this unit, the student should be able to:

7.1.4 Common Misunderstandings

Some common misunderstandings include the following:

7.2 C++ object model: copy semantics

Skeleton instructions are typeset in italic text.

7.2.1 Overview

Provides a short natural language abstract of the module’s contents. Specifies the different levels of teaching.

Level Objectives
Foundational understanding how and when are copies made
Main implementing user-defined copy operations
Advanced special cases: copy elision

7.2.2 Motivation

Why is this important? Why do we want to learn/teach this topic?

Copy semantics allows the user to define how objects of a class get replicated and interact on a value level.

7.2.3 Topic introduction

Very brief introduction to the topic.

Explains when and how objects are copied.

7.2.4 Foundational: How and when are copies made

7.2.4.1 Background/Required Knowledge

A student is able to: * explain what a C++ type is? [C++ object model: types] * explain what an object is? [C++ object model: objects], [C++ object model: constant objects] * define and understand class invariants?

It helps when a student is able to: * use move semantics [C++ object model: move semantics] * explain special member functions [C++ object model: special member functions]

7.2.4.2 Student outcomes

A list of things “a student should be able to” after the curriculum. The next word should be an action word and testable in an exam. Max 5 items.

A student should be able to:

  1. explain what copy semantics accomplish
  1. explain difference between copying a reference and copying a value*
  2. explain where copies are made

* In other languages these differences are sometimes referred to as shallow and deep copy.

7.2.4.3 Caveats

This section mentions subtle points to understand, like anything resulting in implementation-defined, unspecified, or undefined behavior.

7.2.4.4 Points to cover

This section lists important details for each point.

7.2.5 Main: Implementing user-defined copy operations

7.2.5.1 Background/Required Knowledge

A student is able to: * identify special member functions [C++ object model: special member functions]

It helps when a student is able to: * use move semantics [C++ object model: move semantics] * explain the rule of zero [C++ object model: rule-of-zero] * explain the rule of five [C++ object model: rule-of-five]

7.2.5.2 Student outcomes

A list of things “a student should be able to” after the curriculum. The next word should be an action word and testable in an exam. Max 5 items.

A student should be able to: * explain when they have to implement the copy operations for their own type * Copy constructor * Copy assignment operator * implement copy operations for their own types * Optional: explain when copying with basic and strong exception guarantees is useful

7.2.5.3 Caveats

This section mentions subtle points to understand, like anything resulting in implementation-defined, unspecified, or undefined behavior.

7.2.5.4 Points to cover

This section lists important details for each point.

7.2.6 Advanced

These are important topics that are not expected to be covered but provide guidance where one can continue to investigate this topic in more depth.

When can copies be elided and when does the standard guarantee copy elision. References: * Abseil tip of the Week #166 * cppreference - Copy elision

7.3 Functions: user-defined literals

Skeleton instructions are typeset in italic text.

7.3.1 Overview

Provides a short natural language abstract of the module’s contents. Specifies the different levels of teaching.

Level Objectives
Foundational using and understanding UDLs
Main implementing your own UDLs
Advanced Advanced use (“{}, {}!”_fmt(“Hello”, “World”))

7.3.2 Motivation

Why is this important? Why do we want to learn/teach this topic?

7.3.3 Topic introduction

Very brief introduction to the topic.

7.3.4 Foundational: Using UDLs

7.3.4.1 Background/Required Knowledge

A student: * knows how to form numeric literals, e.g., 1.5f means a float of value 1.5. * is familiar with the major C++ types: * bool (Boolean type) * int (Integer type) * double (Floating-point type) * std::string (Text type) * std::vector (Collection type) * knows that namespaces exist, and namespace std. * knows what using-declarations and using-directives are. [C++ object model: declarations]

7.3.4.2 Student outcomes

A list of things “a student should be able to” after the curriculum. The next word should be an action word and testable in an exam. Max 5 items.

A student should be able to:

  1. use using namespace std::string_literals[1].
  2. recognise UDLs in code that they are reading.
  3. figure out which UDL definitions for a used type exist.
  4. identify parts of the standard library that make use of UDLs.
  5. prevent the dangers of temporaries created with "blah"s as well as with std::string{"blah"}.
  6. effectively selects the right set of namespaces in using-directives from the sub-namespaces std::literals.

[1]: explain that it’s okay to use a using-directive to “activate” UDLs.

7.3.4.3 Caveats

This section mentions subtle points to understand, like anything resulting in implementation-defined, unspecified, or undefined behavior.

7.3.4.4 Points to cover

This section lists important details for each point.

7.3.5 Main: implementing UDLs

7.3.5.1 Background/Required Knowledge

7.3.5.2 Student outcomes

A list of things “a student should be able to” after the curriculum. The next word should be an action word and testable in an exam. Max 5 items.

A student should be able to:

  1. write a UDL operator of their own.
  2. separate unrelated UDLs into distinct namespaces.

7.3.5.3 Caveats

This section mentions subtle points to understand, like anything resulting in implementation-defined, unspecified, or undefined behavior.

No caveats at present. #### Points to cover

This section lists important details for each point.

No caveats at present. ### Advanced {#udl-advanced}

These are important topics that are not expected to be covered but provide guidance where one can continue to investigate this topic in more depth.

7.4 Functions: default argument

Skeleton instructions are typeset in italic text.

7.4.1 Overview

Functions in C++ may be overloaded with different numbers and types of parameters. It may be of value to specify default arguments for some number of parameters, to allow a caller to avoid specifying arguments that rarely change, or to enable expanding the set of parameters while maintaining backward compatibility with existing callers.

Level Objectives
Foundational Define and use functions with default arguments
Main
Advanced refinement of default arguments through multiple declarations

7.4.2 Motivation

Default arguments allow the omission of arguments with obvious or common values. Also may be utilized to extend an existing function signature without forcing changes to existing calling code.

7.4.3 Topic introduction

Explain how default arguments work and how to define them.

7.4.4 Foundational: Using and defining functions with default arguments

7.4.4.1 Background/Required Knowledge

A student is able to:

7.4.4.2 Student outcomes

A student should be able to:

  1. Call to a function with a default argument with or without that argument specified
  2. Declare a function with a default argument, and omit the default in the definition’s signature
  3. Explain when the lifetime of a default argument begins and ends

7.4.4.3 Caveats

7.4.4.4 Points to cover

7.4.5 Main: implementing *

7.4.5.1 Background/required knowledge

7.4.5.2 Student outcomes

A student should be able to:

7.4.5.3 Caveats

7.4.5.4 Points to cover

7.4.6 Advanced

Subsequent redeclarations of the same function may add default argument values, which are then usable by callers. Though a single parameter cannot be given a default argument twice in the same translation unit, it is legal, though ill-advised, to give the same function different default arguments in different translation units.

7.5 Module name: Requires Expressions

7.5.1 Overview

Level Objectives
Foundational Define and use requires-expressions to check satisfaction of expressions by given parameters
Main Define and use requires-expressions to check properties of expressions
Advanced

7.5.2 Motivation

Requires-expressions allow a developer to perform compile-time evaluation on the validity of other expressions. These are fundamental to the ability to write concepts. [Compile-time programming: concepts]

7.6 Topic introduction

Requires-expressions are compile-time predicates which evaluate to true when their specified set of expressions are all valid for a given set of inputs.

7.6.1 Foundational: Writing requires-expressions

7.6.1.1 Background/Required Knowledge

A student is able to:

It is helpful if:

7.6.1.2 Student outcomes

A student should be able to:

  1. Write a simple-requirement to assert the validity of an expression
  2. Write a type-requirement to check the existence of a type by its identifier
  3. Write a compound-requirement to test the resulting type of an expression
  4. Write a nested-requirement to test the constexpr value of an operation, as opposed to just the syntactic validity
  5. Use a requires-expression within a concept, requires-clause, or if constexpr condition

7.6.1.3 Caveats

To require that expressions, which evaluate to a boolean value like sizeof(t) == 4, evaluate to true a nested-requirement is needed (e.g., requires sizeof(t) == 4;). Omitting the requires results in a simple-requirement, which is satisfied based purely on syntactic validity, not on the result of the operation.

7.6.1.4 Points to cover

7.6.2 Main: Advanced requirements

7.6.2.1 Background/required knowledge

A student is able to:

7.6.2.2 Student outcomes

A student should be able to:

  1. Write compound-requirements which test the noexceptness of an expression.
  2. Use a concept as the target of a compound-requirement.

7.6.2.3 Caveats

7.6.2.4 Points to cover

static_assert(requires(S s) { { s.foo() } noexcept; } ); // Succeeds. s.foo() is noexcept static_assert(requires(S s) { { s.bar() } noexcept; } ); // Fails. s.bar() is not noexcept ``* If the return-type-requirement of a compound-requirement is a concept, that concept is given the resulting type as the first parameter, followed by the specified parameters in the compound-requirement.{ ++x } -> Cwould substituteC<decltype((++x)), int>` and check that concept C is satisfied for those parameters.

7.6.3 Advanced

8 Examples of Course Curricula

[NOTE: Anyone have any suggestions of items to add here?] The following are examples of curricula for course on C++: …

9 Glossary

10 References

10.1 References on Learning Outcomes

11 License

[NOTE: This license is copied from the C++ Core Guidelines.]

Copyright (c) Standard C++ Foundation and its contributors

Standard C++ Foundation grants you a worldwide, nonexclusive, royalty-free,
perpetual license to copy, use, modify, and create derivative works from this
project for your personal or internal business use only. The above copyright
notice and this permission notice shall be included in all copies or
substantial portions of the project. This license does not grant permission
to use the trade names, trademarks, service marks, or product names of the
licensor, except as required for reasonable and customary use in describing
the origin of the project.

Standard C++ Foundation reserves the right to accept contributions to the
project at its discretion.

By contributing material to this project, you grant Standard C++ Foundation,
and those who receive the material directly or indirectly from Standard C++
Foundation, a perpetual, worldwide, non-exclusive, royalty-free, irrevocable,
transferrable license to reproduce, prepare derivative works of, publicly
display, publicly perform, and distribute your contributed material and such
derivative works, and to sublicense any or all of the foregoing rights to third
parties for commercial or non-commercial use.  You also grant Standard C++
Foundation, and those who receive the material directly or indirectly from
Standard C++ Foundation, a perpetual, worldwide, non-exclusive, royalty-free,
irrevocable license under your patent claims that directly read on your
contributed material to make, have made, use, offer to sell, sell and import
or otherwise dispose of the material. You warrant that your material is your
original work, or that you have the right to grant the above licenses.

THE PROJECT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE PROJECT OR THE USE OR OTHER DEALINGS IN THE
PROJECT.

If you believe that anything in the project infringes your copyright, please
contact us at admin@isocpp.org with your contact information and a detailed
description of your intellectual property, including a specific URL where you
believe your intellectual property is being infringed.

12 Contributors

For a complete list of contributors, please refer to the repository containing this document on GitHub.

13 Outstanding Issues

See the file named TODO.txt (in the project’s Git repository) for more details.