![]() | This user page needs to be updated. Please help update this user page to reflect recent events or newly available information. (July 2025) |
C++ language revisions |
---|
C++26 is the informal name for the version of the International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC) 14882 standard for the C++ programming language that follows C++23. The current working draft of this version is N5008.[1]
An ISO C++ committee chair Herb Sutter has characterized the revision as the most impactful release since C++11, asserting that this revision is likely to change the way programmers develop software in C++. The revision marks the pivotal evolution for the language's compile-time and safety capabilities.
The revision included major additions, such as contracts, first-class reflection, and the new asynchronous model.
[TODO: all sources and examples came straight from cppreference]
Core Language Features
editMost of the newly introduced language features are designed to alleviate the reliance on verbose idioms, workarounds, and excessive boilerplate code. These features offer direct and standardized constructs in place of previously ad hoc solutions while expanding the expressiveness and flexibility of the language.
Runtime Safety
editReading from uninitialized automatic variables now yields erroneous behavior, a formally defined category. The new standard specifies how they behave rather than treating them as undefined behavior.
The new attribute [[indeterminate]]
restores the undefined behavior that was implicitly introduced until C++26. It may make compilers consider a code path reading an indeterminate value unreachable.
void f(int);
void g()
{
int x [[indeterminate]]; // indeterminate value
int y; // erroneous value
f(x); // undefined behavior
f(y); // erroneous behavior
}
struct T
{
T() {}
int x;
};
void h(T a [[indeterminate]], T b)
{
f(a.x); // undefined behavior when called below
f(b.x); // erroneous behavior when called below
}
h(T(), T());
Trivial Relocation
editTODO: source wg21.link/p2786r13
A new operation named relocation is defined as the act of moving an object from one memory ___location to another. The operation is akin to ending the lifetime of the source object, but not necessarily calling the destructor of the source object, and starting the lifetime of a new object at a new ___location. For most types that support move construction and destruction, a relocation can be accomplished by calling the move constructor of the target object from the source object, followed by invoking the destructor of the source object.
More importantly, trivial relocation is mostly used operation defined as a relocation accomplished by performing a bitwise copy (such as std::memcpy
) of the source object's object representation to a new memory ___location that ends the lifetime of that source object.
Trivial relocation can be used to optimize std::vector
moving elements into a new buffer when the allocator does not implement construct and destroy.
Extensions to Compile-time Programming
editBinary Resource Inclusion
editPreviously, programmers have been using softwares such as xxd or python scripts to generate static array data from a binary resource file. The new preprocessor directive #embed
now allows for direct binary resource inclusion to the executable whether it be icons, scripts, or images.
const unsigned char icon_display_data[] = {
#embed "art.png"
};
User-defined Static Assertion Messages
editThe error message of a static_assert
could now be any constant expression producing a sequence of characters rather than be limited to string literals. This would allow libraries doing work at compile-time be able to better diagnose the exact problem.
consteval std::string_view get_error_msg();
template <typename T>
void check_add(T a, T b)
{
static_assert(std::is_integral_v<T>, get_error_msg());
}
Promotion to Static Data
editNew functions std::define_static_array
, std::define_static_string
, and std::define_static_object
promote objects to static data.
The new transient allocation introduced in C++20 are too strict because it does not allow the allocated data from the new
to persist at runtime:
consteval std::vector<int> get_numbers() { /* ... */ }
constexpr auto numbers = get_numbers(); // error
This new feature allows the data of get_numbers()
to persist at runtime at the cost of increasing the binary size.
constexpr auto numbers = std::define_static_array(get_numbers()); // ok
The function std::define_static_array
returns a std::span
object instead of std::vector
.
Constexpr References and Structured Bindings
editTODO: add
Constant Evaluated Blocks
editNewly introduced consteval
blocks that can be inserted in any declaration. This is needed to work with the new injected declaration feature.
Relaxing Constant Evaluation Restrictions
editEach new standard loosens the restrictions of the evaluation of the constant evaluation such as dynamic allocation and dynamic polymorphism in C++20. In C++26, this continues to relax the restrictions of constant evaluations.
Since C++26, the constant evaluation now allows:
- cast from
void*
toT*
such that the pointer must be either a null pointer value or an address pointing to an object whose type is similar toT
, - placement
new
, - caught, and
- virtual inheritance.
Extensions to Templates
editVariable template and concepts as template parameters
editThe template-template parameter now accepts variable templates and concepts.
template <template <typename T> concept C, template <typename T> auto V>
struct S {};
template <typename T>
concept Concept = true;
template <typename T>
constexpr auto Var = 42;
S<Concept, Var> s;
Structured Binding Pack
editStructured binding pack is a new kind of pack that allows objects to be decomposed into packs. However, these packs can only be declared in a template definition, like in the function template.
template <typename Tuple>
constexpr auto into_tuple(Tuple& t) {
auto& [...args] = t;
return std::tie(args...);
}
Pre-C++26 code involved boilerplates to construct a tuple from any aggregate object to mimic the same behavior. This behavior is used as a workaround to iterate over members of a struct.
Pack Indexing
editEvery element of the pack can now be accessed through pack indexing with the syntax pack...[Index]
.
Expansion Statements
editThis is a new kind of statement, which is just a template expansion of the body mimicking the behavior of a range-based for loop. This is another way to iterate over members of a struct and any tuple-like object instead of idiomatic workarounds.
template <typename Tuple>
constexpr auto print_tuple(const Tuple& tup) {
template for (const auto& item : tup)
std::println("{}", item);
}
The same behavior can be achieved without expansion statements, but with a different code and also involves pack expansion:
template <typename Tuple>
constexpr auto print_tuple(const Tuple& tup) {
std::apply([](const auto&... items) {
(std::println("{}", items), ...);
}, tup);
}
Other Template Features
edit- Variadic friends.
- Ordering of constraints involving fold expressions.
Reflection
editTODO: reference wg21.link/p2996
Reflection Operator and Splicing
editMetafunctions
editInjected Declarations
editAnnotations
editMost declarations can now be attached with annotations, which are just values associated with that declaration. Annotations are different from attributes because they allow arbitrary constants to be attached, making them customizable to programs, unlike attributes. This allows for bridging the communication between the library API and the user.
enum class [[=custom::enum_flag]] Toggle {
Off, On
};
struct [[=custom::debug]] Person {
[[=custom::rename("full name")]] std::string full_name;
int age;
};
The annotations have no initial meaning unless some implementations use those annotations to identify some characteristics and features.
Other Language Features
edit- Unevaluated strings.
- Adding
@
,$
, and`
to the basic character set. - Placeholder variables with no name.
- Attributes for structured bindings.
= delete("reason");
- Structured binding declaration as a condition.
- Deleting a pointer to an incomplete type should be ill-formed.
constexpr
structured bindings and references toconstexpr
variables.- Oxford variadic comma, i.e. "Deprecate ellipsis parameters without a preceding comma. The syntax
(int...)
is incompatible with C, detrimental to C++, and easily replaceable with(int, ...)
."[3] - Removing deprecated array comparisons.
Standard Library Features
edit- Hashing support for
std::chrono
value classes std::is_within_lifetime
- Native handles in file streams
- Interfacing string streams with
std::string_view
- Interfacing
std::bitset
withstd::string_view
- More
constexpr
for<cmath>
and<complex>
- Adding the new 2022 SI prefixes on ratios:
std::quecto
,std::ronto
,std::ronna
, andstd::quetta
std::copyable_function
std::submdspan()
<contracts>
: Design-by-contract support<debugging>
: Debugging support and language features to aid debugger programs<hazard_pointer>
: Hazard pointers for threading<hive>
: Hive data structure support which reuses erased elements' memory<inplace_vector>
: In-place vector data structure support, which is a resizable, fixed capacity, inplace contiguous array<linalg>
: A free function linear algebra interface based on the BLAS<meta>
: Compile-time reflection support<rcu>
: Support for safe reclamation read-copy-update mechanism<simd>
: Data-parallel access (Single instruction, multiple data or SIMD) support<text_encoding>
: Support for accessing the IANA Character Sets registry- Support for annotations to be used in reflection which behave differently from the existing attribute system used by the compiler
- Added tuple protocol to
std::complex
views::concat
- Concatenation of strings and string views
std::ranges::generate_random
- Printing blank lines with
std::println()
std::formatter<std::filesystem::path>
- Saturation arithmetic with, among others,
std::add_sat
,std::div_sat
External links
editReferences
edit- ^ "Working Draft, Standard for Programming Language C++" (PDF). Open Standards. ISO/IEC. 2025-03-15.
- ^ "Contract assertions (since C++26) - cppreference.com". en.cppreference.com. Retrieved 2025-03-09.
- ^ "P3176R1: The Oxford variadic comma". eisenwave.github.io. Retrieved 2024-12-09.