The C++23 standard break-down
source link: https://mariusbancila.ro/blog/2022/12/23/the-cpp23-standard-break-down/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
The C++23 standard break-down
It’s almost the eve of 2023 and the C++23 standard is feature complete for some while. At some point next year, the new standard version will be formally approved and we will officially have a new version of the standard. But compilers and library implementors are already supporting some of the new additions (or updates) to the standard. If you haven’t been following closely the evolution of C++23 you are probably wondering what’s in this new version.
In this article, you will find a list of the most significant changes to the standard. There is actually quite a long list of proposals that have been accepted . Yet, some of these are things that you won’t use that often; on the other hand, many are defect reports, meaning they are fixing an issue introduced in a previous version of the standard.
You can find the entire list of changes at cppreference.com. This page doesn’t only list the C++23 features, but also which compiler supports them. However, to help you get an overview of what are the significant parts of C++23, I have curated the following tables, where you will find a short description for each entry as well as links to articles and papers where you can learn more about each feature.
C++23 Core Language Features
Search | ||
---|---|---|
Feature | Description | Links |
Literal suffix for size_t | Adds uz (UZ or any combination) as a literal suffix for std::size_t .Adds z or Z as literal suffixed for the signed integral type corresponding to std::size_t . | P0330R8: Literal Suffix for (signed) size_t Integer literal Three C++23 features for common use |
if consteval | Behaves like if (std::is_constant_evaluated()) { } but does not require including a special header and can be used to invoke immediate functions. | P1938R3: if consteval consteval if |
auto(x) and auto{x} | auto(x) and auto{x} enable casting x into a prvalue as if passing x as a function argument by value | P0849R8: auto(x): decay-copy in the language |
#elifdef and #elifndef | #elifdef id is equivalent to #elif defined id #elifndef id is equivalent to #elif !defined id | P2334R1: Add support for preprocessing directives elifdef and elifndef conditional inclusion |
#warning | Generate a diagnostic message from the preprocessor without stopping translation. | P2437R1: Support for #warning Diagnostic directives |
deducing this | Gives a new way of specifying non-static member functions which enables de-quadruplication of code, recursive lambdas, passing this by value, and a version of the CRTP which doesn’t require the base class to be templated on the derived class. | P0847R7: Deducing this Member functions: Explicit object parameter C++23’s Deducing this: what it is, why it is, how to use it C++23: Deducing this |
Labels at the end of compound statements | Allows labels to be present at the end of a compound statement. | P2324R2: Labels at the end of compound statements (C compatibility) |
Multidimensional subscript operator | User-defined types can define a subscript operator with multiple arguments to better support multi-dimensional containers and views. | P2128R6: Multidimensional subscript operator Three C++23 features for common use C++23’s new function syntax |
static operator() | Allow the call operator of a class to be a static member function to improve generated code. | P1169R4: static operator() |
static operator[] | For consistency with the static call operator. | P2589R0: static operator[] |
[[assume]] attribute | Provides a way to tell the compiler to assume that a given C++ expression is true, without evaluating it, and to optimise based on this assumption. | P1774R8: Portable assumptions C++ attribute: assume C++23: attributes |
C++23 Library Features
Search | ||
---|---|---|
Feature | Description | Links |
Stacktrace library | Support for printing the backtrace of the call sequence, which is useful for debugging and post mortem debugging. | P0881R7: A Proposal to add stacktrace library P2301R1: Add a pmr alias for std::stacktrace C++23: The stacktrace library |
std::expected and the <expected> header | A wrapper type that stores either an expected value of a type T , or an unexpected value of a type E . Intended for returning values from functions that could fail and otherwise throw an exception on failure. | P0323R12: std::expected P2505R5: Monadic Functions for std::expected Standard library header <expected> Using the C++23 std::expected type C++23 - std::expected, the superior way of returning a value or an error Expect the expected |
std::mdspan and the <mdspan> header | An extension of the std::span class to enable multi-dimensional arrays. | P0009R18: MDSPAN std::mdspan A Gentle Introduction to mdspan C++23 Feature Freeze: Summer ISO WG21 Meeting Results |
std::flat_map /std::flat_multimap and the <flat_map> header | Container adaptors that behave like a map /multimap but rely on sequence containers not binary trees providing faster iteration, random access iterators, and smaller memory consumption at the expense of slower insertions and deletions. | P0429R9: A Standard flat_map Standard library header <flat_map> C++23: flat_map, flat_set, et al. |
std::flat_set /std::flat_multiset and the <flat_set> header | Container adapters that behave like a set /multiset but use sequence containers for storying their elements. Similar benefits and disadvantages to std::flat_map /std::flat_multimap . | P1222R4: A Standard flat_set Standard library header <flat_set> C++23: flat_map, flat_set, et al. |
std::print /std::println and the <print> header | An improved way of printing formatting text to the standard output console that is not only simpler, more performant (because it produces less binary code) but also supports Unicode, allowing programmers to write Unicode text portably with standard APIs. | P2093R14: Formatted output Standard library header <print> |
std::basic_spanbuf /std::basic_spanstream and the <spanstream> header | An alternative to the deprecated std::strstream consisting of the basic_spanbuf class and the stream class templates basic_ispanstream , basic_ospanstream , and basic_spanstream that enable the use of streams of externally provided memory buffers, with no ownership and no reallocations. | P0448R4: A strstream replacement using span<charT> as buffer Standard library header <spanstream> 6 C++23 features improving string and string_view |
std::to_underlying | A utility function (from the <utility> header) that converts an enumeration to its underlying type. It is basically syntactic sugar for the expression static_cast<std::underlying_type_t<Enum>>(e) . | P1682R3: std::to_underlying for enumerations std::to_underlying Three new utility functions in C++23 |
basic_string::contains() and basic_string_view::contains() | Member functions for string and string_view that allows to check whether a sub-string or a single character is present anywhere in the string. | P1679R3: string contains function std::basic_string::contains Three C++23 features for common use |
std::byteswap() | A utility function (from the <bit> header) for reversing the bytes of an integral value. | P1272R4: Byteswapping for fun&&nuf std::byteswap Three new utility functions in C++23 |
std::unreachable() | A utility function (from the <utility> header) that allows programmers to tell the compiler that a certain execution path cannot be reached, so that it could better optimize impossible code branches. | P0627R6: Function to mark unreachable code std::unreachable Three new utility functions in C++23 |
Monadic operations for std::optional | Adds new member functions map , and_then , and or_else to std::optional enabling chaining together computations which may or may not produce a value. | P0798R8: Monadic operations for std::optional std::optional The Functional Side of std::optional with C++20 |
std and std.compat modules | import std; imports everything in namespace std from C++ headers and C wrapper headers. import std.compat; imports all of the above, plus the global namespace counterparts for the C wrapper headers. | P2465R3: Standard Library Modules std and std.compat C++ 23 to introduce module support |
C++23 Ranges Library Features
Search | ||
---|---|---|
Feature | Description | Links |
ranges::fold | Folding algorithms for ranges: fold , fold1 , fold_right | P2322R6: ranges::fold |
std::ranges::starts_with and std::ranges::ends_with | Algorithms that check whether a range matches the beginning of another range (starts_with ) or the ending (ends_with ). | P1659R3:starts_with and ends_with std::ranges::starts_with std::ranges::ends_with |
ranges::contains and ranges::contains_subrange | Two algorithms that checks whether or not a range contains an element (ranges::contains ), and one that checks whether or not a range contains a subrange (ranges::contains_subrange ). | P2302R4: std::ranges::contains std::ranges::contains, std::ranges::contains_subrange |
ranges::find_last , ranges::find_last_if , ranges::find_last_if_not | Three new algorithms that return the last element in a range that satisfy a specific criteria. | P1223R5: find_last std::ranges::find_last, std::ranges::find_last_if, std::ranges::find_last_if_not |
ranges::to | A function that can convert any range to a container, including non-standard and recursive ones. | P1206R7: Conversions from ranges to containers std::ranges::to Ranges Improvements with C++23 |
ranges::iota , ranges::shift_left , and ranges::shift_right | Matching ranges algorithms for their generic counterparts. | P2440R1: ranges::iota, ranges::shift_left, and ranges::shift_right std::ranges::iota std::ranges::shift_left, std::ranges::shift_right |
views::zip | A range adaptor that takes one or more views, and produces a view whose ith element is a tuple-like value consisting of the ith elements of all views. | P2321R2: zip std::ranges::views::zip New C++23 range adaptors |
views::zip_transform | A range adaptor that takes an invocable object and one or more views, and produces a view whose ith element is the result of applying the invocable object to the ith elements of all views. | P2321R2: zip std::ranges::views::zip_transform Ranges Improvements with C++23 |
views::adjacent | A range adaptor that takes a view, and produces a view whose ith element is a std::tuple that holds N references to the elements of the original view. | P2321R2: zip std::ranges::views::adjacent Ranges Improvements with C++23 |
views::adjacent_transform | A range adaptor that takes a view and an invocable object fun , and produces a view whose i th element is a value that is the result of applying fun to each element in [i, i + N) of the original view. | P2321R2: zip std::ranges::views::adjacent_transform |
views::join_with | A range adapter that flattens a range of ranges of T into a range of T . | P2441R2: views::join_with std::ranges::views::join_with New C++23 range adaptors |
views::chunk | A range adapter that divides a range R into non-overlapping N -sized chunks, except that the last chunk can be smaller than N in size. | P2442R1: Windowing range adaptors: views::chunk and views::slide std::ranges::views::chunk |
views::chunk_by | A range adapter that takes a view and a predicate, and splits the view into subranges between each pair of adjacent elements for which the predicate returns false. | P2443R1: views::chunk_by std::ranges::views::chunk_by |
views::slide | A range adapter that takes a view R and a number N and produces a range of ranges such that the M -th range is a view into the M -th through (M+N-1) -th elements of R . It is similar to views::adjacent , except that the size of the window N is provided at runtime. | P2442R1: Windowing range adaptors: views::chunk and views::slide std::ranges::views::slide |
views::stride | A range adaptor that takes a view and a number N and produces a view, that consists of elements of the original view by advancing over N elements at a time. | P1899R3: stride_view std::ranges::views::stride Ranges Improvements with C++23 |
views::cartesian_product | A range adapter that produces the cartesian product of any number of ranges. | P2374R4: views::cartesian_product Understand ranges better with the new Cartesian Product adaptor |
views::as_rvalue | A range adaptor that represents a view of underlying view whose elements are rvalues. | P2446R2: views::as_rvalue std::ranges::views::as_rvalue |
views::repeat | A range factory which creates a range that repeats the same value either infinitely, or a specified number of times. | P2474R2: views::repeat std::ranges::views::repeat |
std::generator | A standard library type which implements a coroutine generator that models std::ranges::input_range . | P2502R2: std::generator: Synchronous Coroutine Generator for Ranges C++ 23 Status Report C++23 Feature Freeze: Summer ISO WG21 Meeting Results |
Conclusions
The C++23 version of the standard contains many new entries but overall if feels a lesser increment comparing to the C++17 and C++20 versions. I find it difficult to pinpoint any core language feature that stands out in the list. I could perhaps mention std::expected
, std::print
and monadic operations for std::optional
when it comes to the standard library, as well as the several additions to the ranges library.
On the other hand, I’d appreciate if you tell us what are your favorite features or which one do you think are the most important.
Like this:
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK