# C++20

C++20 is a version of the ISO/IEC 14882 standard for the C++ programming language. C++20 replaced the prior version of the C++ standard, called C++17, and was later replaced by C++23. The standard was technically finalized by WG21 at the meeting in Prague in February 2020, had its final draft version announced in March 2020, was approved on 4 September 2020, and published in December 2020.

## Features

C++20 adds more new major features than C++14 or C++17. Changes that have been accepted into C++20 include:

### Language

* concepts, with terse syntax
* modules
* designated initializers (based on the C99 feature, and common g++ extension)
* [=, this] as a lambda capture
* template parameter lists on lambdas
* three-way comparison using the "spaceship operator", operator <=>
* initialization of an additional variable within a range-based for statement
* lambdas in unevaluated contexts
* default constructible and assignable stateless lambdas
* allow pack expansions in lambda init-capture
* class types in non-type template parameters, also allowing string literals as template parameters
* removing the need for typename in certain circumstances
* new standard attributes [[no_unique_address]], [[likely]] and [[unlikely]]
* conditional explicit, allowing the explicit modifier to be contingent on a Boolean expression
* expanded constexpr: virtual functions, union, try and catch, dynamic_cast and typeid, std::pointer_traits
* immediate functions using the new consteval keyword
* signed integers are now defined to be represented using two's complement (signed integer overflow remains undefined behavior)
* a revised memory model
* various improvements to structured bindings (interaction with lambda captures, static and thread_local storage duration)
* coroutines
* using on scoped enums
* constinit keyword

### Library

* ranges (The One Ranges Proposal)
* std::make_shared and std::allocate_shared for arrays
* atomic smart pointers (such as std::atomic<shared_ptr<T>> and std::atomic<weak_ptr<T>>)
* std::to_address to convert a pointer to a raw pointer
* calendar and time-zone additions to <chrono>
* std::span, providing a view to a contiguous array (analogous to std::string_view but span can mutate the referenced sequence)
* std::erase and std::erase_if, simplifying element erasure for most standard containers
* <version> header
* std::bit_cast<> for type casting of object representations, with less verbosity than memcpy and more ability to exploit compiler internals
* feature test macros
* various constexpr library bits
* smart pointer creation with default initialization
* contains-method for associative containers
* bit operations, such as leading/trailing zero/one count, and log2 operations
* std::bind_front

### New and changed keywords

Many new keywords added (and the new "spaceship operator", operator <=>), such as concept, constinit, consteval, co_await, co_return, co_yield, requires (plus changed meaning for export), and char8_t (for UTF-8 support). And explicit can take an expression since C++20. Most of the uses of the volatile keyword have been deprecated.
In addition to keywords, there are identifiers with special meaning, including new import and module.
New attributes in C++20: [[likely]], [[unlikely]], and [[no_unique_address]]

### Removed and deprecated

Removed features:
* The C-derived headers <ccomplex>, <ciso646>, <cstdalign>, <cstdbool> and <ctgmath> were removed, as they serve no purpose in C++. (The corresponding <*.h> headers remain, for compatibility with C.)
* The use of throw as an exception specification was removed.
* Some previously deprecated library features were removed, including std::uncaught_exception, std::raw_storage_iterator, std::is_literal_type, std::is_literal_type_v, std::result_of and std::result_of_t.
Deprecated features:
* Use of comma operator in subscript expressions has been deprecated
* (most of) volatile has been deprecated

## Published as Technical Specifications

* Parallelism TS v2 (including task blocks)
* Reflection TS v1
* Networking TS v1

## Deferred to a later standard

* Contracts – a new study group (SG21) has been formed to work on a new proposal
* Reflection
* Metaclasses
* Executors
* Networking extensions, including async, basic I/O services, timers, buffers and buffer-oriented streams, sockets, and Internet protocols (blocked by executors)
* Properties
* Extended futures

## Compiler support

Full support
* Visual Studio 2019 supports all C++20 features through its /std:c++latest option, as of version 16.10.0. An option /std:c++20 to enable C++20 mode is added in version 16.11.0.
Microsoft's compiler supports not only Windows but also Linux, Android, and iOS. However, for Linux development, it requires the "Visual C++ for Linux Development" extension.
Partial
* Clang has partial C++20 support that can be enabled with the option -std=c++20 (version 10 and later) or -std=c++2a (version 9 and earlier).
* EDG started implementing C++20 features in version 5.0 and as of version 6.1 supports most C++20 core language features.
* GCC added partial, experimental C++20 support in 2017 in version 8 through the option -std=c++2a. Like Clang, GCC replaced this option with -std=c++20 in version 10. It also has an option to enable GNU extensions in addition to the experimental C++20 support, -std=gnu++20.

## History

Changes applied to the C++20 working draft in July 2017 (Toronto) include:
* concepts (what made it into the standard is a cut-down version; also described as "Concepts Lite")
* designated initializers
* [=, this] as a lambda capture
* template parameter lists on lambdas
* std::make_shared and std::allocate_shared for arrays
Changes applied to the C++20 working draft in the fall meeting in November 2017 (Albuquerque) include:
* three-way comparison using the "spaceship operator", operator <=>
* initialization of an additional variable within a range-based for statement
* lambdas in unevaluated contexts
* default constructible and assignable stateless lambdas
* allow pack expansions in lambda init-capture
* string literals as template parameters
* atomic smart pointers (such as std::atomic<shared_ptr<T>> and std::atomic<weak_ptr<T>>)
* std::to_address to convert a pointer to a raw pointer
Changes applied to the C++20 working draft in March 2018 (Jacksonville) include:
* removing the need for typename in certain circumstances
* new standard attributes [[no_unique_address]], [[likely]] and [[unlikely]]
* calendar and time-zone additions to <chrono>
* std::span, providing a view to a contiguous array (analogous to std::string_view but span can mutate the referenced sequence)
* <version> header
Changes applied to the C++20 working draft in the summer meeting in June 2018 (Rapperswil) include:
* contracts (later deferred to a later standard)
* feature test macros
* bit-casting of object representations, with less verbosity than memcpy and more ability to exploit compiler internals
* conditional explicit, allowing the explicit modifier to be contingent on a Boolean expression
* constexpr virtual functions
Changes applied to the C++20 working draft in the fall meeting in November 2018 (San Diego) include:
* ranges (The One Ranges Proposal)
* concept terse syntax
* constexpr union, try and catch, dynamic_cast, typeid and std::pointer_traits.
* various constexpr library bits
* immediate functions using the new consteval keyword
* signed integers are now defined to be represented using two's complement (signed integer overflow remains undefined behavior)
* refinements of the contracts facility (access control in contract conditions) (see list of features deferred to a later standard)
* a revised memory model
* smart pointer creation with default initialization
Changes applied to the C++20 working draft in the winter meeting in February 2019 (Kona) include:
* coroutines
* modules
* various improvements to structured bindings (interaction with lambda captures, static and thread_local storage duration)
Changes applied to the C++20 working draft in the summer meeting in July 2019 (Cologne) include:
* contracts were removed (see list of features deferred to a later standard)
* use of comma operator in subscript expressions has been deprecated
* constexpr additions (trivial default initialization, unevaluated inline-assembly)
* using scoped enums
* various changes to the spaceship operator
* DR: minor changes to modules
* constinit keyword
* changes to concepts (removal of -> Type return-type-requirements)
* (most of) volatile has been deprecated
* DR: [[nodiscard]] effects on constructors
* The new standard library concepts will not use PascalCase (rather standard_case, as the rest of the standard library)
* text formatting (std::format, chrono integration, corner case fixes)
* bit operations
* constexpr INVOKE
* math constants
* consistency additions to atomics (std::atomic_ref<T>, std::atomic<std::shared_ptr<T>>)
* add the <=> operator to the standard library
* header units for the standard library
* synchronization facilities (merged from: Efficient atomic waiting and semaphores, latches and barriers, Improving atomic_flag, Don't Make C++ Unimplementable On Small CPUs)
* std::source_location
* constexpr containers (std::string, std::vector)
* std::stop_token and joining thread (std::jthread)
Changes applied during the NB comment resolution in the fall meeting in November 2019 (Belfast) include:
* Class Types in Non-Type Template Parameters (NTTP): The restriction of no user-defined operator== allowed has been removed as the meaning of template argument equality has been divorced from operator==. This allows also for array members in class-type NTTP.
* Floating-point types, pointers and references and unions and union-like classes (class types containing anonymous unions) are now allowed as NTTP.
* Function identity now also includes trailing requires-clauses (P1971)
* Constrained non-template functions have been removed
* <compare> is now available in freestanding implementations
* std::spans typedef was changed from index_type to size_type to be consistent with the rest of the standard library
* Concept traits have been renamed to follow the renaming of the concepts as a result from the Cologne meeting
* Several fixes and additions to ranges (P1456R1: Move-only views, P1391R4: Range constructor for std::string_view (constructor from iterator-pair of characters), P1394R4: Range constructor for std::span<ref>, P1870R1: forwarding-range<T> is too subtle)
* Initialization for std::atomic<T> has been changed to make it work with default and list initialization, std::latch and std::barrier can now report the maximum number of threads that the implementation supports through the new member function max
* std::weak_equality and std::strong_equality have been removed as they are not used anymore
* Algorithms in <numeric> have been made constexpr
* Missing feature-test macros for new or changed features of C++20 have been added