
This video will give you an overview about the course.
Examine the standardization process timeline. Check which features are included in the new standard and which are left as a technical specification.
• Identify four major features of C++20
• Identify important technical specifications
• Assess the scope of changes introduced in the new standard
Examine compiler support table that shows which language feature is supported by which compiler.
• Examine the support for language features
• Examine the support for library features
• Examine the features that have no support at all
Consider problem of building examples using different compilers for each section.
• Check how to enable/disable the examples for a section
• Build latest GCC from sources
• Invoke CMake and make use of the newly compiled GCC
Why new standard formatting? A new library which was type safe, concise, extendable, flexible, and efficient. Available mechanism did not have all these qualities; therefore string formatting library was born using {fmt} library as the foundation.
• Print a hex number filled with zeros using stdio and iostreams
• Consider code from previous example, using std::format to achieve the same result
• Compare std::format to stdio and iostreams. Consider error handling of std::format
This video shows formal syntax for formatting library mini language and how to use placeholders and placeholder IDs.
• Define simple text with integers and switch placeholders using IDs
• Consider formal syntax of std::format and compare to stdio
• Consider performance of std::format compared to other IO
This video explains how std::format_to and std::format_to_n work, and how to safely format text to std::vector<char> and c array.
• Format text to std::vector<char> using std::back_inserter
• Format text to std::vector<char> but preallocate memory, by getting the required size using std::formatted size
• Format text to c array using std::format_to_n
This video shows how to define formatting for user defined type.
• Define struct person
• Define stream insertion operator for person
• Test printing person object using std::cout and std::format
This video explains how to migrate to new string formatting from stdio or iostreams-based code. It also shows how to get working implementation if it is not yet shipped with the standard library.
• Consider inc.hpp contants and its usage of {fmt} library
• Consider changes required to migrate code from iostreams or stdio to std::format
• Consider how std::format interacts with stdio and iostreams in printing logs
Passing pair of iterators to algorithms makes them difficult to compose. Code that uses algorithms is verbose and does not facilitate functional programming.
• Convert a pair of pointers to a range
• Use constrained algorithms
• Compose the calls using bitwise OR operator
Ranges do not act as a glue between containers and constrained algorithms. They provide composability and non-modifying views with lazy evaluation.
• Define what a range is
• Define the difference between a view and a container
• Understand how those features can be used to write a better code
Consider range generators and range adaptors.
• Understand how range generators create an infinite range in a lazy way
• Study range generators and range adaptors provided by the standard library
• Understand how to use them
We need to write a piece of code that filters out even numbers from a container and returns them multiplied by two. In other example we take n integers from container and compute their squares.
• Use views: filter and transform
• Use views: iota and transform
• Compare resulting code with the code that uses iterators
Define a type that supports all standard relational operators in pre C++20 and using new defaulted three-way comparison operator.
• Define the six member operators
• Define only <=> operator
• Test both solutions
How the spaceship operator is supposed to be used? How do you compare two values using this operator? How does comparing the return value against literal zero work?
• Test return value of comparing integers and verify it’s std::strong_ordering
• Test return value of comparing two floats and verify it’s std::partial_ordering
• Test that in std::partial ordering none of the available comparisons may compare true
How is defaulted three-way comparison operator able to handle all standard comparisons, even if it is the type that supports it is on right hand side?
• Discuss rewriting expressions
• Discuss synthetizing expressions
• Verify that thanks to these two operations all comparisons are supported
Verify that if we define three-way comparison then equality will not be defined for us.
• Test equality with defaulted three-way comparison operator
• Test equality with custom three-way comparison operator
• Test equality with additionally defined equality operator
What are the types returned by the spaceship operator? What members do they have? How can they be converted to each other?
• Discuss all types returned by the spaceship operator
• Discuss the comparison against zero
• Discuss how these types can be converted to one another
Include directives cause long compilation times and unclear separation of interface from implementation.
• See size of preprocessed file
• See number of lines from preprocessed file
• Learn to include directive deficiencies
Split module into two separate module interface partitions
• Split module into module interface and module implementation files
• Compile and run the examples
• Compile and run the example
Split module from 5.2 into two separate module interface partitions. Afterwards split same module into module interface file and module implementation file.
Learn how to compile and link modular code using Clang 9 and GCC 10 compiled from C++-modules branch.
• Learn which compilers have working modules implementation
• Compile, link, and run example four using GCC
• Compile, link, and run example four using Clang
Call sort algorithm on std::list container and analyze error output produced by the compiler.
• Consider length of error output
• Consider cause of error
• Concepts are the solution
Define function template comp that uses three-way comparison operator and pass a type that does not support it.
• Consider compiler error diagnostics
• Implement ThreeWayComparable concept and apply to comp template function
• Consider improved error diagnostics
Implement mySort wrapper to std::sort function. Use the function incorrectly.
• Consider compiler error diagnostics
• Constrain function using RandomAccessIterator and LessThanComparable concepts
• Consider improved error diagnostics
Implement mysort wrapper to std::sort overload that takes comparison function. Pass invalid comparison function to the wrapper.
• Consider compiler error diagnostics
• Constrain function using concepts from standard library: std::invocable and std::totally_ordered
• Consider improved error diagnostics
Analyze thread sanitizer output for modifying value of std::shared_ptr.
• Modify just the control block and examine the output
• Modify pointer value and examine the output
• Introduce a solution, which is the shared atomic pointer
Analyze an example with wait method called on atomic variable.
• Examine documentation for the wait method
• Modify value an atomic variable
• Use notify_all to wake up all threads waiting on this variable
Use std::counting_semaphore to synchronize two threads.
• Examine documentation for std::counting_semaphore
• Analyze pattern of using acquire and release methods
• Check if the synchronization is working as expected
Use std::latch and std::barrier to synchronize incrementing atomic value from two separate threads.
• Consider latch and barrier initialization values (participating threads)
• Analyze the usage of std::latch::count_down_and_wait() and std::barrier::arrive_and_wait()
• Examine wakeup conditions in synchronization points for both a latch and a barrier
Why are coroutines needed at all? What are coroutines?
• Prepare a synchronous piece of code
• Rewrite the code to be asynchronous, using threading
• Rewrite the code again using coroutines
How are coroutines different from threads?
• Discuss how threading works
• Discuss how coroutines work
• Discuss the difference between execution thread and state of execution
Here, discuss new keywords and when and how does a function becomes a coroutine.
• Discuss what new tools coroutines provide the programmers with
• Discuss what is missing from coroutines
• Discuss how and when does a function become a coroutine and what it consists of
Define a simple Fibonacci function with a co_yield expression.
• Define a Fibonacci function
• Add generator definition using raw coroutines facilities
• Add generator definition using cppcoro template
Define simple producer – consumer pair of coroutines and switching between them.
• Define consumer coroutine
• Define producer coroutine
• Use cppcoro::single_consumer_event facility to make it work
This section shows how to avoid retyping long fully qualified names of enum class values, especially those enclosed in classes.
• Consider example with enum class enclosed in a class and switch statement using its values
• Use “using enum” statement to bring values to current scope
• Consider how switch statement is simplified
Consider generic lambda expressions and problem of interacting with the type of argument. Write generic lambda accepting argument of vector holding objects of any type.
• Write generic lambda using “auto” keyword in place of type of arguments
• Consider compiler output when passing a type that is not a vector
• Fix the problem by adding <typename T> and explicit std::vector<T> to lambda definition
Consider a struct with default values for fields. Without a constructor the syntax to initialize it with only single value different than the default is awkward.
• Consider using designated initializers to change one of the default values
• Consider using designated initializers to assign previously unassigned string field
• Compile, run, and verify if all values are set as expected
Consider problem of defining a function that can only be executed at compile time and defining a variable that can only be initialized at compile time.
• Define a static variable using constinit specifier
• Define a function using consteval specifier
• Try to use the variable and the function in non-static context
In this video, you’ll learn about the course summary.
• Discuss the overview of the course
• Discuss the next steps after this course
C++ is popular for its incredible performance and suitability for operating systems, games, embedded software, and more. This course gets you up-to-date with the very latest components in C++20/C++2a so you can harness its new enhancements and get ahead of the game by leveraging its features!
We cover what C++20/C++2a is and the current standardization status. We also discover some new syntactic sugars that enable you to write shorter but more powerful code. You'll learn about the new and improved ranges and iterators, explore key examples of filter stacking, and learn how ranges simplify iterator-heavy code. Crucially, you'll master how to migrate to C++20/C++2a in the easiest possible way, and why you should!
C++20/C++2a brings new features to the synchronization library, including atomic smart pointers, latchers, and barriers. We review its all-new coroutines (a major concept found in other leading programming languages that simplifies writing code for parallel execution).
By the end of the course, you'll use up-to-date insights into the full features of C++20/C++2a to facilitate efficient and fast coding within your own projects.
About the Author
Daniel Zawadzki is a software developer with 15 years' experience. His career has mostly focused on embedded development for various devices such as phones, set-top boxes, and mobile telephony base stations, though he did make a slight detour into investment banking along the way. His language of choice (he has over 5 years' experience with it) is C++ because of its efficiency and predictable resource usage. Currently, his interests revolve around the architecture of distributed systems. He lives in Wrocław, Poland.