# C++ 2023

ISO C++ 2023

In this implementation the `-std=gnu++23` or `-std=c++23` flag must be used to enable language and library features. See dialect options. The pre-defined symbol `__cplusplus` is used to check for the presence of the required flag.

This section describes the C++23 and library TS support in the GCC 14 release series.

The following table lists new library features that have been accepted into the C++23 working draft. The "Proposal" column provides a link to the ISO C++ committee proposal that describes the feature, while the "Status" column indicates the first version of GCC that contains an implementation of this feature (if it has been implemented). A dash (—) in the status column indicates that the changes in the proposal either do not affect the code in libstdc++, or the changes are not required for conformance. The "SD-6 Feature Test / Notes" column shows the corresponding macro or header from SD-6: Feature-testing recommendations for C++ (where applicable) or any notes about the implementation.

C++ 2023 Library Features

Library Feature | Proposal | Status | SD-6 Feature Test / Notes
--- | --- | --- | ---
Ranges and Views
Range constructor for std::string_view | P1989R2 | 11.1 |
`join_view` should join all views of ranges | P2328R1 | 11.2 |
Clarifying range adaptor objects | P2281R1 | 11.1 |
Views should not be required to be default constructible | P2325R3 | 11.3 | `__cpp_lib_ranges >= 202106L`
Conditionally borrowed ranges | P2017R1 | 11.1 |
Require `span` & `basic_string_view` to be Trivially Copyable | P2251R1 | Yes |
Repairing input range adaptors and counted_iterator | P2259R1 | 12.1 |
Superior String Splitting | P2210R2 | 12.1 |
What is a `view`? | P2415R2 | 12.1 | `__cpp_lib_ranges >= 202110L`
Fix istream_view | P2432R1 | 12.1 |
`starts_with` and `ends_with` | P1659R3 |  | `__cpp_lib_ranges_starts_ends_with >= 202106L`
`zip` | P2321R2 | 13.1 | `__cpp_lib_ranges_zip >= 202110L`
`views::repeat` | P2474R2 | 13.1 | `__cpp_lib_ranges_repeat >= 202207L`
`views::enumerate` | P2164R9 | 13.1 | `__cpp_lib_ranges_enumerate >= 202302L`
`views::join_with` | P2441R2 | 13.1 | `__cpp_lib_ranges_join_with >= 202202L`
Windowing range adaptors: `views::chunk` and `views::slide` | P2442R1 | 13.1 | `__cpp_lib_ranges_slide >= 202202L`
`views::chunk_by` | P2443R1 | 13.1 | `__cpp_lib_ranges_chunk_by >= 202202L`
`views::stride` | P1899R3 | 13.1 | `__cpp_lib_ranges_stride >= 202207L`
`views::cartesian_product` | P2374R4 | 13.1 | `__cpp_lib_ranges_cartesian_product >= 202207L`
Empty Product for certain Views | P2540R1 | 13.1 | `__cpp_lib_ranges_cartesian_product >= 202207L`
`views::as_rvalue` | P2446R2 | 13.1 | `__cpp_lib_ranges_as_rvalue >= 202207L`
`cbegin` should always return a constant iterator | P2278R4 | 13.1 | `__cpp_lib_ranges_as_const >= 202207L`
`ranges::to` | P1206R7 | 14.1 (`ranges::to` function) | `__cpp_lib_containers_ranges >= 202202L`, `__cpp_lib_ranges_to_container >= 202202L`
Ranges iterators as inputs to non-Ranges algorithms | P2408R5 |  | `__cpp_lib_algorithm_iterator_requirements >= 202207L`
Pipe support for user-defined range adaptors | P2387R3 | 13.1 | `__cpp_lib_bind_pack >= 202202L`, `__cpp_lib_ranges >= 202202L`
`ranges::iota`, `ranges::shift_left`, and `ranges::shift_right` | P2440R1 | 13.1 (`ranges::iota`) | `__cpp_lib_ranges_iota >= 202202L`, `__cpp_lib_shift >= 202202L`
`ranges::find_last` | P1223R5 | 13.1 | `__cpp_lib_ranges_find_last >= 202207L`
`ranges::contains` | P2302R4 | 13.1 | `__cpp_lib_ranges_contains >= 202207L`
Making multi-param constructors of views explicit | P2711R1 |  |
`ranges::fold` | P2322R6 | 13.1 | `__cpp_lib_ranges_fold >= 202207L`
Relaxing Ranges Just A Smidge | P2609R3 |  | `__cpp_lib_ranges >= 202302L`
Compile-time programming
A proposal for a type trait to detect scoped enumerations | P1048R1 | 11.1 | `__cpp_lib_is_scoped_enum >= 202011L`
std::to_underlying for enumerations | P1682R3 | 11.1 | `__cpp_lib_to_underlying >= 202102L`
Missing constexpr in std::optional and std::variant | P2231R1 |
11.3 (`optional`)
12.1 (`variant`)
`__cpp_lib_constexpr_optional >= 202106L`
`__cpp_lib_variant >= 202106L`
Making `std::unique_ptr` constexpr | P2273R3 | 12.1 | `__cpp_lib_constexpr_memory >= 202202L`
Making `std::type_info::operator==` constexpr | P1328R1 | 12.1 | `__cpp_lib_constexpr_typeinfo >= 202106L`
constexpr for `<cmath>` and `<cstdlib>` | P0533R9 |  | `__cpp_lib_constexpr_cmath >= 202202L`
Deprecate std::aligned_storage and std::aligned_union | P1413R3 |  |
A type trait to detect reference binding to temporary | P2255R2 |
13.1 (missing changes to `std::tuple`)
14.1 (complete)
| `__cpp_lib_reference_from_temporary >= 202202L`
Move-only types for equality_comparable_with, totally_ordered_with, and three_way_comparable_with | P2404R3 |  | `__cpp_lib_concepts >= 202207L`
A trait for implicit lifetime types | P2674R1 |  | `__cpp_lib_is_implicit_lifetime >= 202302L`
`common_reference_t` of `reference_wrapper` Should Be a Reference Type | P2655R3 |  | `__cpp_lib_common_reference >= 202302L`
Deprecate `numeric_limits::has_denorm` | P2614R2 |  |
Containers
Iterator pair constructors for stack and queue | P1425R4 | 12.1 | `__cpp_lib_adaptor_iterator_pair_constructor >= 202106L`
Stop overconstraining allocators in container deduction guides | P1518R2 | 12.1 |
Heterogeneous erasure overloads for associative containers | P2077R3 |  | `__cpp_lib_associative_heterogeneous_erasure >= 202110L`
`<flat_map>` | P0429R9 |  | `__cpp_lib_flat_map >= 202207L`
`<flat_set>` | P1222R4 |  | `__cpp_lib_flat_set >= 202207L`
`mdspan` | P0009R18 |  | `__cpp_lib_mdspan >= 202207L`
`index_type` & `size_type` in `mdspan` | P2599R2 |  | `__cpp_lib_mdspan >= 202207L`
`mdspan`: rename `pointer` and `contiguous` | P2604R0 |  | `__cpp_lib_mdspan >= 202207L`
Add the missing `empty` to `mdspan` | P2613R1 |  | `__cpp_lib_mdspan >= 202207L`
`layout_stride` static extents default constructor fix | P2763R1 |  |
Strings and text
string contains function | P1679R3 | 11.1 | `__cpp_lib_string_contains >= 202011L`
Prohibit std::basic_string and std::basic_string_view construction from nullptr | P2166R1 | 12.1 |
basic_string::resize_and_overwrite | P1072R10 | 12.1 | `__cpp_lib_resize_and_overwrite >= 202110L`
A strstream replacement using span<charT> as buffer | P0448R4 | 12.1 | `__cpp_lib_spanstream >= 202106L`
`std::string::substr() &&` | P2438R2 |  |
std::format improvements | P2216R3 | 13.1 | `__cpp_lib_format >= 202106L`
Add support for `std::generator`-like types to `std::format` | P2418R2 | 13.1 | `__cpp_lib_format >= 202110L`
Expose `std::basic-format-string<charT, Args...>` | P2508R1 | 13.1 (feature test macro not defined) | `__cpp_lib_format >= 202207L`
Clarify handling of encodings in localized formatting of chrono types | P2419R2 |  | `__cpp_lib_format >= 202207L`
Formatting pointers | P2510R3 | 13.2 (feature test macro not defined) | `__cpp_lib_format >= 202207L`
Formatting Ranges | P2286R8 |  | `__cpp_lib_format_ranges >= 202207L`
Improve default container formatting | P2585R1 |  | `__cpp_lib_format_ranges >= 202207L`
Formatted output | P2093R14 | 14.1 | `__cpp_lib_print >= 202207L`
Should the output of std::print to a terminal be synchronized with the underlying stream? | P2539R3 | 14.1 |
Formatting `thread::id` and `stacktrace` | P2693R1 | 14.1 | `__cpp_lib_formatters >= 202302L`
Add Constexpr Modifiers to Functions `to_chars` and `from_chars` for Integral Types in `<charconv>` Header | P2291R3 | 13.1 | `__cpp_lib_constexpr_charconv >= 202207L`
Miscellaneous
Inheriting from `std::variant` | P2162R2 | 11.3 | `__cpp_lib_variant >= 202102L`
Printing `volatile` Pointers | P1147R1 | 11.3 |
A Proposal to add stacktrace library | P0881R7 | 12.1 | `__cpp_lib_stacktrace >= 202011L`
Add a pmr alias for std::stacktrace | P2301R1 | 12.1 |
`std::expected` | P0323R12 | 12.1 | `__cpp_lib_expected >= 202202L`
Monadic operations for std::expected | P2505R5 | 13.1 | `__cpp_lib_expected >= 202211L`
Monadic operations for std::optional | P0798R8 | 12.1 | `__cpp_lib_optional >= 202110L`
Compatibility between `tuple`, `pair` and tuple-like objects | P2165R4 | 14.1 | `__cpp_lib_tuple_like >= 202207L`
Default Arguments for `pair`'s Forwarding Constructor | P1951R1 | 14.1 |
`move_only_function` | P0288R9 | 12.1 | `__cpp_lib_move_only_function >= 202110L`
`invoke_r` | P2136R3 | 12.1 | `__cpp_lib_invoke_r >= 202106L`
Byteswapping for fun&&nuf | P1272R4 | 12.1 | `__cpp_lib_byteswap >= 202110L`
Function to mark unreachable code | P0627R6 | 12.1 | `__cpp_lib_unreachable >= 202202L`
Add a conditional noexcept specification to std::exchange | P2401R0 | 12.1 |
A more constexpr bitset | P2417R2 | 13.1 | `__cpp_lib_constexpr_bitset >= 202207L`
Extended floating-point types and standard names | P1467R9 | 13.1 |
Support C atomics in C++ | P0943R6 | 12.1 | `__cpp_lib_stdatomic_h >= 202011L`
Clarifying the status of the "C headers" | P2340R1 | Yes |
Relax Requirements for time_point::clock | P2212R2 | Yes |
Removing Garbage Collection Support | P2186R2 | 12.1 |
Easy [utilities], [ranges], and [iterators] | P1642R11 | 13.1 |
Providing size feedback in the Allocator interface | P0401R6 |  | `__cpp_lib_allocate_at_least >= 202306L`
Disallow User Specialization of `allocator_traits` | P2652R2 |  |
Explicit lifetime management | P2590R2 |  | `__cpp_lib_start_lifetime_as >= 202207L`
Fixing `std::start_lifetime_as` and `std::start_lifetime_as_array` | P2679R2 |  |
out_ptr - a scalable output pointer abstraction | P1132R8 | 14.1 | `__cpp_lib_out_ptr >= 202106L`
`barrier`'s phase completion guarantees | P2588R3 |  | `__cpp_lib_barrier >= 202302L`
Standard Library Modules `std` and `std.compat` | P2465R3 |  | `__cpp_lib_modules >= 202207L`