Preface
- An Experiment
- Acknowledgments
- Versions of This Book
About This Book
- What You Should Know Before Reading This Book
- Overall Structure of the Book
- How to Read This Book
- The Way I Implement
- Initializations
- Error Terminology
- Code Simplifications
- The C++ Standards
- Example Code and Additional Information
- Feedback
1.Comparisons and Operator <=>
- 1.1Motivation for Operator
<=> - 1.1.1Defining Comparison Operators Before C++20
- 1.1.2Defining Comparison Operators Since C++20
- 1.2Defining and Using Comparisons
- 1.2.1Using Operator
<=> - 1.2.2Comparison Category Types
- 1.2.3Using Comparison Categories with
operator<=> - 1.2.4Calling Operator
<=>Directly - 1.2.5Dealing with Multiple Ordering Criteria
- 1.3Defining
operator<=>andoperator== - 1.3.1Defaulted
operator==andoperator<=> - 1.3.2Defaulted
operator<=>Implies Defaultedoperator== - 1.3.3Implementation of the Defaulted
operator<=> - 1.4Overload Resolution with Rewritten Expressions
- 1.5Using Operator
<=>in Generic Code - 1.5.1
compare_three_way - 1.5.2Algorithm
lexicographical_compare_three_way() - 1.6Compatibility Issues with the Comparison Operators
- 1.6.1Delegating Free-Standing Comparison Operators
- 1.6.2Inheritance with Protected Members
- 1.7Afternotes
2.Placeholder Types for Function Parameters
- 2.1
autofor Parameters of Ordinary Functions - 2.1.1
autofor Parameters of Member Functions - 2.2Using
autofor Parameters in Practice - 2.2.1Deferred Type Checks with
auto - 2.2.2
autoFunctions versus Lambdas - 2.3
autofor Parameters in Detail - 2.3.1Basic Constraints for
autoParameters - 2.3.2Combining Template and
autoParameters - 2.4Afternotes
3.Concepts, Requirements, and Constraints
- 3.1Motivating Example of Concepts and Requirements
- 3.1.1Improving the Template Step by Step
- 3.1.2A Complete Example with Concepts
- 3.2Where Constraints and Concepts Can Be Used
- 3.2.1Constraining Alias Templates
- 3.2.2Constraining Variable Templates
- 3.2.3Constraining Member Functions
- 3.2.4Constraining Non-Type Template Parameters
- 3.3Typical Applications of Concepts and Constraints in Practice
- 3.3.1Using Concepts to Understand Code and Error Messages
- 3.3.2Using Concepts to Disable Generic Code
- 3.3.3Using Requirements to Call Different Functions
- 3.3.4The Example as a Whole
- 3.3.5Former Workarounds
- 3.4Semantic Constraints
- 3.4.1Examples of Semantic Constraints
- 3.5Design Guidelines for Concepts
- 3.5.1Concepts Should Group Requirements
- 3.5.2Define Concepts with Care
- 3.5.3Concepts versus Type Traits and Boolean Expressions
- 3.6Afternotes
4.Concepts, Requirements, and Constraints in Detail
- 4.1Constraints
- 4.2
requiresClauses - 4.2.1Using
&&and||inrequiresClauses - 4.3Ad-hoc Boolean Expressions
- 4.4
requiresExpressions - 4.4.1Simple Requirements
- 4.4.2Type Requirements
- 4.4.3Compound Requirements
- 4.4.4Nested Requirements
- 4.5Concepts in Detail
- 4.5.1Defining Concepts
- 4.5.2Special Abilities of Concepts
- 4.5.3Concepts for Non-Type Template Parameters
- 4.6Using Concepts as Type Constraints
- 4.7Subsuming Constraints with Concepts
- 4.7.1Indirect Subsumptions
- 4.7.2Defining Commutative Concepts
5.Standard Concepts in Detail
- 5.1Overview of All Standard Concepts
- 5.1.1Header Files and Namespaces
- 5.1.2Standard Concepts Subsume
- 5.2Language-Related Concepts
- 5.2.1Arithmetic Concepts
- 5.2.2Object Concepts
- 5.2.3Concepts for Relationships between Types
- 5.2.4Comparison Concepts
- 5.3Concepts for Iterators and Ranges
- 5.3.1Concepts for Ranges and Views
- 5.3.2Concepts for Pointer-Like Objects
- 5.3.3Concepts for Iterators
- 5.3.4Iterator Concepts for Algorithms
- 5.4Concepts for Callables
- 5.4.1Basic Concepts for Callables
- 5.4.2Concepts for Callables Used by Iterators
- 5.5Auxiliary Concepts
- 5.5.1Concepts for Specific Type Attributes
- 5.5.2Concepts for Incrementable Types
6.Ranges and Views
- 6.1A Tour of Ranges and Views Using Examples
- 6.1.1Passing Containers to Algorithms as Ranges
- 6.1.2Constraints and Utilities for Ranges
- 6.1.3Views
- 6.1.4Sentinels
- 6.1.5Range Definitions with Sentinels and Counts
- 6.1.6Projections
- 6.1.7Utilities for Implementing Code for Ranges
- 6.1.8Limitations and Drawbacks of Ranges
- 6.2Borrowed Iterators and Ranges
- 6.2.1Borrowed Iterators
- 6.2.2Borrowed Ranges
- 6.3Using Views
- 6.3.1Views on Ranges
- 6.3.2Lazy Evaluation
- 6.3.3Caching in Views
- 6.3.4Performance Issues with Filters
- 6.4Views on Ranges That Are Destroyed or Modified
- 6.4.1Lifetime Dependencies Between Views and Their Ranges
- 6.4.2Views with Write Access
- 6.4.3Views on Ranges That Change
- 6.4.4Copying Views Might Change Behavior
- 6.5Views and
const - 6.5.1Generic Code for Both Containers and Views
- 6.5.2Views May Remove the Propagation of
const - 6.5.3Bringing Back Deep Constness to Views
- 6.6Summary of All Container Idioms Broken By Views
- 6.7Afternotes
7.Utilities for Ranges and Views
- 7.1Key Utilities for Using Ranges as Views
- 7.1.1
std::views::all() - 7.1.2
std::views::counted() - 7.1.3
std::views::common() - 7.2New Iterator Categories
- 7.3New Iterator and Sentinel Types
- 7.3.1
std::counted_iterator - 7.3.2
std::common_iterator - 7.3.3
std::default_sentinel - 7.3.4
std::unreachable_sentinel - 7.3.5
std::move_sentinel - 7.4New Functions for Dealing with Ranges
- 7.4.1Functions for Dealing with the Elements of Ranges (and Arrays)
- 7.4.2Functions for Dealing with Iterators
- 7.4.3Functions for Swapping and Moving Elements/Values
- 7.4.4Functions for Comparisons of Values
- 7.5New Type Functions/Utilities for Dealing with Ranges
- 7.5.1Generic Types of Ranges
- 7.5.2Generic Types of Iterators
- 7.5.3New Functional Types
- 7.5.4Other New Types for Dealing with Iterators
- 7.6Range Algorithms
- 7.6.1Benefits and Restrictions for Range Algorithms
- 7.6.2Algorithm Overview
8.View Types in Detail
- 8.1Overview of All Views
- 8.1.1Overview of Wrapping and Generating Views
- 8.1.2Overview of Adapting Views
- 8.2Base Class and Namespace of Views
- 8.2.1Base Class for Views
- 8.2.2Why Range Adaptors/Factories Have Their Own Namespace
- 8.3Source Views to External Elements
- 8.3.1Subrange
- 8.3.2Ref View
- 8.3.3Owning View
- 8.3.4Common View
- 8.4Generating Views
- 8.4.1Iota View
- 8.4.2Single View
- 8.4.3Empty View
- 8.4.4IStream View
- 8.4.5String View
- 8.4.6Span
- 8.5Filtering Views
- 8.5.1Take View
- 8.5.2Take-While View
- 8.5.3Drop View
- 8.5.4Drop-While View
- 8.5.5Filter View
- 8.6Transforming Views
- 8.6.1Transform View
- 8.6.2Elements View
- 8.6.3Keys and Values View
- 8.7Mutating Views
- 8.7.1Reverse View
- 8.8Views for Multiple Ranges
- 8.8.1Split and Lazy-Split View
- 8.8.2Join View
9.Spans
- 9.1Using Spans
- 9.1.1Fixed and Dynamic Extent
- 9.1.2Example Using a Span with a Dynamic Extent
- 9.1.3Example Using a Span with Non-
constElements - 9.1.4Example Using a Span with Fixed Extent
- 9.1.5Fixed vs. Dynamic Extent
- 9.2Spans Considered Harmful
- 9.3Design Aspects of Spans
- 9.3.1Lifetime Dependencies of Spans
- 9.3.2Performance of Spans
- 9.3.3
constCorrectness of Spans - 9.3.4Using Spans as Parameters in Generic Code
- 9.4Span Operations
- 9.4.1Span Operations and Member Types Overview
- 9.4.2Constructors
- 9.4.3Operations for Sub-Spans
- 9.5Afternotes
10.Formatted Output
- 10.1Formatted Output by Example
- 10.1.1Using
std::format() - 10.1.2Using
std::format_to_n() - 10.1.3Using
std::format_to() - 10.1.4Using
std::formatted_size() - 10.2Performance of the Formatting Library
- 10.2.1Using
std::vformat()andvformat_to() - 10.3Formatted Output in Detail
- 10.3.1General Format of Format Strings
- 10.3.2Standard Format Specifiers
- 10.3.3Width, Precision, and Fill Characters
- 10.3.4Format/Type Specifiers
- 10.4Internationalization
- 10.5Error Handling
- 10.6User-Defined Formatted Output
- 10.6.1Basic Formatter API
- 10.6.2Improved Parsing
- 10.6.3Using Standard Formatters for User-Defined Formatters
- 10.6.4Using Standard Formatters for Strings
- 10.7Afternotes
11.Dates and Timezones for <chrono>
- 11.1Overview by Example
- 11.1.1Scheduling a Meeting on the 5th of Every Month
- 11.1.2Scheduling a Meeting on the Last Day of Every Month
- 11.1.3Scheduling a Meeting Every First Monday
- 11.1.4Using Different Timezones
- 11.2Basic Chrono Concepts and Terminology
- 11.3Basic Chrono Extensions with C++20
- 11.3.1Duration Types
- 11.3.2Clocks
- 11.3.3Timepoint Types
- 11.3.4Calendrical Types
- 11.3.5Time Type
hh_mm_ss - 11.3.6Hours Utilities
- 11.4I/O with Chrono Types
- 11.4.1Default Output Formats
- 11.4.2Formatted Output
- 11.4.3Locale-Dependent Output
- 11.4.4Formatted Input
- 11.5Using the Chrono Extensions in Practice
- 11.5.1Invalid Dates
- 11.5.2Dealing with
monthsandyears - 11.5.3Parsing Timepoints and Durations
- 11.6Timezones
- 11.6.1Characteristics of Timezones
- 11.6.2The IANA Timezone Database
- 11.6.3Using Timezones
- 11.6.4Dealing with Timezone Abbreviations
- 11.6.5Custom Timezones
- 11.7Clocks in Detail
- 11.7.1Clocks with a Specified Epoch
- 11.7.2The Pseudo Clock
local_t - 11.7.3Dealing with Leap Seconds
- 11.7.4Conversions between Clocks
- 11.7.5Dealing with the File Clock
- 11.8Other New Chrono Features
- 11.9Afternotes
12.std::jthread and Stop Tokens
- 12.1Motivation for
std::jthread - 12.1.1The Problem of
std::thread - 12.1.2Using
std::jthread - 12.1.3Stop Tokens and Stop Callbacks
- 12.1.4Stop Tokens and Condition Variables
- 12.2Stop Sources and Stop Tokens
- 12.2.1Stop Sources and Stop Tokens in Detail
- 12.2.2Using Stop Callbacks
- 12.2.3Constraints and Guarantees of Stop Tokens
- 12.3
std::jthreadin Detail - 12.3.1Using Stop Tokens with
std::jthread - 12.4Afternotes
13.Concurrency Features
- 13.1Thread Synchronization with Latches and Barriers
- 13.1.1Latches
- 13.1.2Barriers
- 13.2Semaphores
- 13.2.1Example of Using Counting Semaphores
- 13.2.2Example of Using Binary Semaphores
- 13.3Extensions for Atomic Types
- 13.3.1Atomic References with
std::atomic_ref<> - 13.3.2Atomic Shared Pointers
- 13.3.3Atomic Floating-Point Types
- 13.3.4Thread Synchronization with Atomic Types
- 13.3.5Extensions for
std::atomic_flag - 13.4Synchronized Output Streams
- 13.4.1Motivation for Synchronized Output Streams
- 13.4.2Using Synchronized Output Streams
- 13.4.3Using Synchronized Output Streams for Files
- 13.4.4Using Synchronized Output Streams as Output Streams
- 13.4.5Synchronized Output Streams in Practice
- 13.5Afternotes
14.Coroutines
- 14.1What Are Coroutines?
- 14.2A First Coroutine Example
- 14.2.1Defining the Coroutine
- 14.2.2Using the Coroutine
- 14.2.3Lifetime Issues with Call-by-Reference
- 14.2.4Coroutines Calling Coroutines
- 14.2.5Implementing the Coroutine Interface
- 14.2.6Bootstrapping Interface, Handle, and Promise
- 14.2.7Memory Management
- 14.3Coroutines That Yield or Return Values
- 14.3.1Using
co_yield - 14.3.2Using
co_return - 14.4Coroutine Awaitables and Awaiters
- 14.4.1Awaiters
- 14.4.2Standard Awaiters
- 14.4.3Resuming Sub-Coroutines
- 14.4.4Passing Values From Suspension Back to the Coroutine
- 14.5Afternotes
15.Coroutines in Detail
- 15.1Coroutine Constraints
- 15.1.1Coroutine Lambdas
- 15.2The Coroutine Frame and the Promises
- 15.2.1How Coroutine Interfaces, Promises, and Awaitables Interact
- 15.3Coroutine Promises in Detail
- 15.3.1Mandatory Promise Operations
- 15.3.2Promise Operations to Return or Yield Values
- 15.3.3Optional Promise Operations
- 15.4Coroutine Handles in Detail
- 15.4.1
std::coroutine_handle<void> - 15.5Exceptions in Coroutines
- 15.6Allocating Memory for the Coroutine Frame
- 15.6.1How Coroutines Allocate Memory
- 15.6.2Avoiding Heap Memory Allocation
- 15.6.3
get_return_object_on_allocation_failure() - 15.7
co_awaitand Awaiters in Detail - 15.7.1Details of the Awaiter Interface
- 15.7.2Letting
co_awaitUpdate Running Coroutines - 15.7.3Symmetric Transfer with Awaiters for Continuation
- 15.8Other Ways of Dealing with
co_await - 15.8.1
await_transform() - 15.8.2
operator co_await() - 15.9Concurrent Use of Coroutines
- 15.9.1
co_awaitCoroutines - 15.9.2A Thread Pool for Coroutine Tasks
- 15.9.3What C++ Libraries Will Provide After C++20
- 15.10Coroutine Traits
16.Modules
- 16.1Motivation for Modules Using a First Example
- 16.1.1Implementing and Exporting a Module
- 16.1.2Compiling Module Units
- 16.1.3Importing and Using a Module
- 16.1.4Reachable versus Visible
- 16.1.5Modules and Namespaces
- 16.2Modules with Multiple Files
- 16.2.1Module Units
- 16.2.2Using Implementation Units
- 16.2.3Internal Partitions
- 16.2.4Interface Partitions
- 16.2.5Summary of Splitting Modules into Different Files
- 16.3Dealing with Modules in Practice
- 16.3.1Dealing with Module Files with Different Compilers
- 16.3.2Dealing with Header Files
- 16.4Modules in Detail
- 16.4.1Private Module Fragments
- 16.4.2Module Declaration and Export in Detail
- 16.4.3Umbrella Modules
- 16.4.4Module Import in Detail
- 16.4.5Reachable versus Visible Symbols in Detail
- 16.5Afternotes
17.Lambda Extensions
- 17.1Generic Lambdas with Template Parameters
- 17.1.1Using Template Parameters for Generic Lambdas in Practice
- 17.1.2Explicit Specification of Lambda Template Parameters
- 17.2Calling the Default Constructor of Lambdas
- 17.3Lambdas as Non-Type Template Parameters
- 17.4
constevalLambdas - 17.5Changes for Capturing
- 17.5.1Capturing
thisand*this - 17.5.2Capturing Structured Bindings
- 17.5.3Capturing Parameter Packs of Variadic Templates
- 17.5.4Lambdas as Coroutines
- 17.6Afternotes
18.Compile-Time Computing
- 18.1Keyword
constinit - 18.1.1Using
constinitin Practice - 18.1.2How
constinitSolves the Static Initialization Order Fiasco - 18.2Keyword
consteval - 18.2.1A First
constevalExample - 18.2.2
constexprversusconsteval - 18.2.3Using
constevalin Practice - 18.2.4Compile-Time Value versus Compile-Time Context
- 18.3Relaxed Constraints for
constexprFunctions - 18.4
std::is_constant_evaluated() - 18.4.1
std::is_constant_evaluated()in Detail - 18.5Using Heap Memory, Vectors, and Strings at Compile Time
- 18.5.1Using Vectors at Compile Time
- 18.5.2Returning a Collection at Compile Time
- 18.5.3Using Strings at Compile Time
- 18.6Other
constexprExtensions - 18.6.1
constexprLanguage Extensions - 18.6.2
constexprLibrary Extensions - 18.7Afternotes
19.Non-Type Template Parameter (NTTP) Extensions
- 19.1New Types for Non-Type Template Parameters
- 19.1.1Floating-Point Values as Non-Type Template Parameters
- 19.1.2Objects as Non-Type Template Parameters
- 19.1.3Lambdas as Non-Type Template Parameters
- 19.2Afternotes
20.New Type Traits
- 20.1New Type Traits for Type Classification
- 20.1.1
is_bounded_array_v<>andis_unbounded_array_v - 20.2New Type Traits for Type Inspection
- 20.2.1
is_nothrow_convertible_v<> - 20.3New Type Traits for Type Conversion
- 20.3.1
remove_cvref_t<> - 20.3.2
unwrap_reference<>andunwrap_ref_decay_t - 20.3.3
common_reference<>_t - 20.3.4
type_identity_t<> - 20.4New Type Traits for Iterators
- 20.4.1
iter_difference_t<> - 20.4.2
iter_value_t<> - 20.4.3
iter_reference_t<>anditer_rvalue_reference_t<> - 20.5Type Traits and Functions for Layout Compatibility
- 20.5.1
is_layout_compatible_v<> - 20.5.2
is_pointer_interconvertible_base_of_v<> - 20.5.3
is_corresponding_member() - 20.5.4
is_pointer_interconvertible_with_class() - 20.6Afternotes
21.Small Improvements for the Core Language
- 21.1Range-Based
forLoop with Initialization - 21.2
usingfor Enumeration Values - 21.3Delegating Enumeration Types to Different Scopes
- 21.4New Character Type
char8_t - 21.4.1Changes in the C++ Standard Library for
char8_t - 21.4.2Broken Backward Compatibility
- 21.5Improvements for Aggregates
- 21.5.1Designated Initializers
- 21.5.2Aggregate Initialization with Parentheses
- 21.5.3Definition of Aggregates
- 21.6New Attributes and Attribute Features
- 21.6.1Attributes
[[likely]]and[[unlikely]] - 21.6.2Attribute
[[no_unique_address]] - 21.6.3Attribute
[[nodiscard]]with Parameter - 21.7Feature Test Macros
- 21.8Afternotes
22.Small Improvements for Generic Programming
- 22.1Implicit
typenamefor Type Members of Template Parameters - 22.1.1Rules for Implicit
typenamein Detail - 22.2Improvements for Aggregates in Generic Code
- 22.2.1Class Template Argument Deduction (CTAD) for Aggregates
- 22.3Conditional
explicit - 22.3.1Conditional
explicitin the Standard Library - 22.4Afternotes
23.Small Improvements for the C++ Standard Library
- 23.1Updates for String Types
- 23.1.1String Members
starts_with()andends_with() - 23.1.2Restricted String Member
reserve() - 23.2
std::source_location - 23.3Safe Comparisons of Integral Values and Sizes
- 23.3.1Safe Comparisons of Integral Values
- 23.3.2
ssize() - 23.4Mathematical Constants
- 23.5Utilities for Dealing with Bits
- 23.5.1Bit Operations
- 23.5.2
std::bit_cast<>() - 23.5.3
std::endian - 23.6
<version> - 23.7Extensions for Algorithms
- 23.7.1Range Support
- 23.7.2New Algorithms
- 23.7.3
unseqExecution Policy for Algorithms - 23.8Afternotes
24.Deprecated and Removed Features
- 24.1Deprecated and Removed Core Language Features
- 24.2Deprecated and Removed Library Features
- 24.2.1Deprecated Library Features
- 24.2.2Removed Library Features
- 24.3Afternotes
Glossary
- A
- aggregate
- argument-dependent lookup (ADL)
- C
- class template argument deduction (CTAD)
- F
- forwarding reference
- full specialization
- function object (functor)
- G
- glvalue
- I
- incomplete type
- L
- lvalue
- P
- partial specialization
- predicate
- prvalue
- R
- resource acquisition is initialization (RAII)
- regular type
- rvalue
- S
- semiregular type
- substitution failure is not an error (SFINAE)
- small string optimization (SSO)
- stateless
- standard template library (STL)
- U
- universal reference
- V
- value category
- variable template
- variadic template
- X
- xvalue
