#cpp26
48 posts tagged #cpp26.
WG21 now says new library types must ship a pmr alias
The worry that pmr is a C++17 experiment the committee abandoned is backwards. WG21's 2024 policy P3002 makes pmr the default vehicle for new allocating types, P1083 brings resource_adaptor in C++26, and P3153 makes optional allocator-aware. A live resource_adaptor demo bridges a classic allocator. Episode 8 of the pmr series.
Getting values out of a match
Numbered captures, named captures, and structured bindings that destructure a match directly. C++26 lets the binding itself be the condition, which removes the trailing test, though one compiler currently disagrees about that inside constant expressions.
C++29 mode is open, and the compilers already disagree
LLVM 23.1 shipped with -std=c++2d, a mode for the standard after C++26, and GCC trunk has one too. Both report __cplusplus as 202700. They do not agree about C++26 itself: GCC says 202603, which is the ratified value, and clang still says 202400.
LLVM 23.1 shipped, and one of its changes is silent
Clang 23.1 landed on 25 August with partial expansion statements, modules dependency discovery, and a batch of core-issue fixes. It also elides more dead stores than 22 did, which is the one change that alters behaviour without saying anything at build time.
Defaulting a destructor costs you both move operations
Howard Hinnant's table tells you which special member functions survive once you declare one yourself. C++26 reflection can check it rather than trusting it, and the result for a defaulted destructor is the one worth internalising: a line that looks like a no-op removes move construction and move assignment.
Who gets to say a feature is not ready
Contracts are in the C++26 working draft. The committee voted against removing them, decisively. Bjarne Stroustrup and four co-authors are asking again anyway, before the final ballot, on the grounds that counting votes is the wrong way to settle whether a foundational feature is finished. Both cases, from the papers.
A C++26 structured binding that GCC and Clang disagree about
C++26 lets a structured binding declaration be the condition of an if. GCC 16.1 and Clang 22.1 both implement it and both agree on ordinary structs. Put a tuple-protocol type in the condition and evaluate it at compile time, and GCC rejects the program while Clang accepts it. The reproducer is twenty lines and needs no library.
C++26 contracts, and the const rule the compiler makes you learn
Contracts are one of the four headline C++26 features and they run on GCC 16.1 today. Two things surprise people on first contact: a by-value parameter named in a postcondition must be const, and what a violation actually does is a compiler flag rather than a property of your code.
GCC 16.2 is out, LLVM 23.1 is nearly there, MSVC is still finishing C++23
GCC 16.2 shipped on 7 August with more than a hundred regression fixes and no new features. LLVM 23.1 reached its third release candidate on 12 August and has not shipped. MSVC has no C++26 date. If you want to write C++26 today, the practical answer remains GCC, and this is where each toolchain actually stands.
std::constant_wrapper carries a compile-time value as an argument
A template parameter is a compile-time value you cannot pass as an argument. A function argument is a runtime value you cannot use as a template parameter. C++26's std::constant_wrapper is an empty object that carries a compile-time value, so it crosses that line: arithmetic on it stays constant, and the result still works as an array extent. GCC 16.1 ships it.
Pattern matching did not make C++26
Enough people assumed pattern matching shipped in C++26 that it is worth stating plainly: it did not. P2688 missed the feature freeze and is now aimed at C++29, no shipping compiler implements it, and until then std::visit with an overload set remains the idiom. Here is what the proposal would actually give you.
Converting between std::function and copyable_function nests them
std::function and std::copyable_function are both type-erased callable wrappers and neither recognises the other. Converting between them does not unwrap and rewrap the lambda inside; it wraps the whole previous wrapper. Round-trip in a loop and every call walks a chain of indirections. In this run, 200 round trips made the same calls several hundred times slower.
std::indirect makes PImpl copyable without writing a copy constructor
PImpl with unique_ptr costs you the special members: hand-written copy operations, a destructor defined where Impl is complete, and const that stops at the pointer. C++26's std::indirect is an indirect value instead of an owning pointer, so it copies deeply and propagates const, and all five special members can be defaulted. GCC 16.1 ships it.
std::inplace_vector is a vector that never touches the heap
C++26 adds std::inplace_vector<T, N>, a sequence container with a fixed compile-time capacity whose storage lives inside the object. It gives you a vector's dynamic size and push_back with zero heap allocation, which is exactly what embedded, real-time, and hot-path code has been hand-rolling for decades. GCC 16.1 ships it now.
C++26 rewrote std::print's internals and backported the fix
std::print's per-call atomicity extends to your own types via std::formatter. How it stays both safe and efficient is a C++26 story: P3107 adds locking-aware entry points and a formatter opt-in to avoid deadlock, and ships as a backport into C++23. Episode 5 of the concurrent I/O series.
Three small C++26 string fixes you will use every day
C++26 quietly closes three long-standing paper cuts in the string library: you can finally write string + string_view, build a stringstream straight from a string_view, and construct a bitset from a view without a temporary. None of them are flashy, all of them remove a copy or a conversion you have been writing for years. Verified on GCC 16.1 and clang-p2996.
C++26 makes an uninitialized read a defined bug
Reading an uninitialized variable has been undefined behavior in C++ since the beginning, and compilers optimize on that assumption. C++26 (P2795) reclassifies it as erroneous behavior: still a bug the compiler diagnoses, but with a defined value and no licence for the optimizer to delete surrounding code. A poisoned-stack demo shows the same source printing garbage under C++23 and a defined 0 under C++26.
Why you can't std::format a smart pointer (and how to anyway)
A recent r/cpp question: std::cout << a unique_ptr works, but std::println("{}", that_unique_ptr) is ill-formed. There is no std::formatter for smart pointers. Is that an oversight? No -- it is a deliberate, sustained decision. Here is the why, and three ways to format a smart pointer today, all verified on Compiler Explorer.
Embed a file at compile time: #embed in C++26
Baking a file into a binary has meant a build step forever: xxd -i, a generated header, a CMake custom command that drifts. C++26 adopts C23's #embed, so a file becomes a literal the compiler reads at translation time. No codegen, no glue. Here it is running on Compiler Explorer.
Structured concurrency: what std::future never had
A std::future is a dead end: you launch it, you get() it once, and composing two of them means manual threads and locks. C++26 senders compose. when_all runs work concurrently and joins it into one result, with no mutex and no leaked threads. Here is the pattern, running on Compiler Explorer.
Hello, sender: your first std::execution pipeline
C++26 shipped three big things: reflection, contracts, and std::execution. The first two get the headlines on this blog. std::execution (P2300) is the new standard model for asynchronous and parallel work, and it is the one most codebases will reach for first. Here is the smallest pipeline that does real work, running today on Compiler Explorer.
reflect_tracing: zero-overhead spans on Maciek Gajewski's ring-buffer engine
Tracing and metrics split into sibling libraries: reflect_telemetry for aggregates over time, reflect_tracing for spans at microsecond resolution. The engine is Maciek Gajewski's 2021 Wro.cpp technique — thread-local ring buffers, ~200 ns per span, function address as payload, DWARF resolution at dump time. Reflection contributes the instrumentation layer, which today is one explicit scope-guard line per function and tomorrow (C++29, P3294/P3157) becomes a pure annotation.
reflect_telemetry: compile-time Prometheus metrics from annotated fields
Every microservice has hand-registered counter() lines that drift from the variable they count. Annotate a field [[=metric(counter)]] and let reflection emit the Prometheus exposition + OpenTelemetry OTLP exporter, keeping names in lockstep with code. Genuinely novel — nobody is doing this yet.
reflect_dx: auto-generated debugger pretty-printers and docs
Every C++ shop writes .natvis files by hand and they go stale. Every C++ shop wishes their headers were documented but can't face Doxygen XML. reflect_dx ships as a build-step tool: walk your headers with reflection, emit LLDB / GDB / Visual Studio pretty-printers + markdown docs. Your struct is your documentation and its debugger visualisation.
Define your own function colors: compile-time caller checks with C++26 reflection
C++ already enforces function colors -- consteval, CUDA's __device__, Clang's [[clang::nonblocking]] -- but every one of them needed a compiler change. C++26's std::meta::current_function() (P3795R1) lets a callee reflect on its caller at compile time, so you can paint your own colors as a 20-line library: audio-thread safety, capability tokens, or architectural layers that refuse to compile when called from the wrong place. Here is the pattern, three professional uses, and exactly where it breaks.
reflect_optics: Haskell-style lenses for C++26
Haskell's lens library has been the gold standard for nested data access for fifteen years. Ports to C++ needed macro hell and never felt right. Reflection makes the pattern genuinely tractable. field<"address.city">(person) is now a first-class, zero-overhead, type-safe, composable lens.
Reflection + annotations for hashing: opt out of fields, not whole structs
Krystian Piekos's May 29 post on infotraining.pl shows the cleanest demo so far of P3394 annotations combined with P2996 reflection: opt structs into hashing with [[=hashable]], and opt individual fields out with [[=skipped_for_hash]]. The Hashable concept and the calculate_hash walker fit in 40 lines. No macros.
reflect_arbitrary: property-based test generators, inferred from your types
QuickCheck in Haskell, mockall in Rust, jqwik in Java — every major language auto-derives Arbitrary<T> from a struct declaration. C++ was last. Reflection fixes that: reflect the struct, recurse into field types, emit a generator. RapidCheck and FuzzTest adapters included.
reflect_llmschema: C++ functions to LLM tool-use schemas, at compile time
In the AI agent era every tool you expose to Claude/GPT needs a JSON-Schema description. Today you write it by hand next to the C++ function. With C++26 reflection, a single consteval call emits the tool-use JSON at compile time — parameter names, types, docstrings, dispatch, done.
Could C++ handle an ABI break? The 2026 case
Two pieces dropped in the same week: Luis Caro Campos' CppCon 2025 talk arguing package managers make ABI breaks manageable, and an HFT University article claiming a 58x P99 latency gap between Rust's and C++'s stdlib. The ABI debate is back. Here is what both sides are saying, and what C++26 shipped despite the constraint.
The fastest JVM is the C++26 compiler
Koen Samyn's BeCPP talk used std::meta::substitute to transform Java bytecode into executable C++ at compile time. The compiler constant-folds the entire program. The loop doesn't run faster. It doesn't exist. This is reflection used not for serialization or enum-to-string, but as a compile-time metaprogramming substrate for building language interpreters.
C++ modules in 2026: import std works, import boost is coming, your IDE still can't
import std compiles on GCC 16.1, Clang 18+, and MSVC. Boost has a per-library module prototype showing 45% build-time reductions. But CMake support is still experimental, clangd needs a full rebuild on module changes, IntelliSense has been 'experimental' for seven years, and almost no libraries ship module definitions. For reflection users: PCH is faster than modules on GCC 16.1 today.
simdjson meets reflection: sb << my_struct at 6.8 GB/s
simdjson now ships a C++26 reflection backend: define SIMDJSON_STATIC_REFLECTION, and sb << my_struct serializes any aggregate at SIMD speed. The CITM Catalog benchmark hits 6.8 GB/s. Combined with P3394 annotations for rename/skip, this is the production JSON path the reflection series has been building toward.
The hidden cost of <meta> -- and the three-line fix
Vittorio Romeo measured what C++26 reflection actually costs: the <meta> header adds ~181ms per TU on GCC 16.1, but the reflection algorithm itself is ~0.07ms per enumerator. The header is 2500x more expensive than the logic. A three-line CMake PCH stanza cuts the header cost by 2.3x. Modules, surprisingly, make it worse.
C++ Safety State of the Union: May 2026
C++ in May 2026 has four conversations running at once: regulators (CISA, EU CRA) demanding memory-safety roadmaps; the committee fighting over how to respond (Hagenberg vote 19 profiles / 9 Safe C++ / 11 both); what actually shipped in C++26 (P2900 contracts, P3471 hardened stdlib, P2996 reflection); and what the industry actually deployed (Chrome MiraclePtr -57% UAF, Google's 0.3% perf-cost data, Apple libc++ safe-buffers). They don't talk to each other in public. This essay wires them. Pre-Brno (8-13 June) reading.
Revzin at C++Now: 'Reflection Is Only Half the Story' -- what generation looks like next
Barry Revzin's C++Now 2026 keynote (Mon 4 May, Aspen) landed the line the C++ reflection community has been circling for two years: C++26 reflection lets you OBSERVE -- the next question is what it looks like to GENERATE. The 90-minute talk is a tour of source-code-generation design space (macros, templates, Rust proc-macros, Swift macros, D mixins) and reads as the natural sequel to wro.cpp's whole 'Where this is heading' triptych framing.
The five most useful things C++26 reflection unlocks (in effort order)
C++26 reflection looks like it requires a PhD in template metaprogramming. It does not. Five concrete projects you can build with it, ranked from five minutes to weeks. Use this as a triage when picking your first reflection-powered project.
Is std::vector consteval or constexpr? A reader's question, answered
A colleague asked: 'Is std::vector consteval and not constexpr?' Short answer: no, but the intuition is right. Long answer: the constexpr/consteval/constinit trio, the transient-allocation rule, and why std::define_static_array exists.
Reflection in the wild: April 2026 in five links
Five things happened to C++26 reflection in April 2026: GCC 16.1, Glaze v7.2, a Revzin write-up, a Lemire/Thiesen JSON talk, and one honest list of what is still not shipping.
Auto-generating std::formatter<T> for any aggregate
Rust's #[derive(Debug)] in C++: make any struct printable via std::format and std::println by dropping in one partial specialisation of std::formatter. Nested types, containers, enum names — all handled.
Glaze v7.2 vs your hand-rolled JSON: a 30-line benchmark
Glaze v7.2 ships a P2996 backend that retires __PRETTY_FUNCTION__, lifts the 128-member cap, and serializes private members. Here is when you still write your own thirty lines -- and when one call wins.
Goodbye magic_enum: enum reflection done right
A reflection-driven enum↔string library in 30 lines. No __PRETTY_FUNCTION__ tricks, no compile-time range knob, no compiler-specific behaviour — and unbounded, including enum values beyond 128.
GCC 16.1 ships C++26 reflection -- your 30-line hands-on
GCC 16.1 dropped on 30 April 2026 with -freflection. C++26 was finalized at Croydon five weeks earlier. Here is a 25-line program you can compile and run today on your laptop.
template for: iterating reflections at compile time
Expansion statements (proposal P1306) unroll a loop at compile time, instantiating the body once per element. They are the natural partner of reflection — one loop, N specialisations.
C++26 is done -- five weeks since Croydon, here's what shipped
Five weeks ago WG21 voted C++26 to publication in Croydon. The dust has settled enough to take stock of what landed, what compiles today, and what it means for the wro.cpp reflection series.
Splicing: [: r :] and putting reflections back into code
Splicing is the inverse of ^^: it takes a std::meta::info and drops the referred entity back into your source. Types, expressions, template arguments, member accesses — all round-trippable.
Your first ^^: reflecting types and walking members
Hands-on introduction to C++26 reflection: the ^^ operator, std::meta::info, and walking struct members. We take the post-1 teaser apart and rebuild it from primitives.
C++26 Reflection: What changes, and why it matters
Part 1 of the C++26 reflection series. A 40-line JSON serializer nobody could write in C++ before 2026 — plus the strategic story of why static reflection changes the ecosystem.