#cpp23
10 posts tagged #cpp23.
What C++23 and C++26 promise about a moved-from function wrapper
None of the standard function wrappers promises an empty source after a move: std::function, move_only_function and copyable_function all leave it valid but unspecified. libstdc++ 16.1 empties all three, libc++ trunk keeps a copy in std::function and does not ship the other two. A small wrapper that states its own move works on both.
The unit travels with the value
Every codebase has a comment like 'speed in m/s' that stopped being true two refactors ago. mp-units plugs quantities into std::format so the unit is printed from the type, with format specs that address the number and the unit separately. Change the unit and the log line follows. Episode 5 of the mp-units series.
A new unit in one line
In 1958 MIT students measured the Harvard Bridge in the body lengths of Oliver Smoot: 364.4 smoots plus one ear. Teaching mp-units the smoot, symbol, exact conversion factor and all, takes one line, and conversions, printing, and derived quantities work immediately. Episode 4 of the mp-units series.
Points are not deltas
The temperature is 21 degrees and the temperature rose by 21 degrees are different quantities, and adding two of the first is meaningless. mp-units models this with the affine space: quantity_point for absolute readings, quantity for changes, and the nonsense operations do not compile. Episode 3 of the mp-units series.
One per second is not one per second
Frequency (Hz), radioactivity (Bq), and angular velocity (rad/s) all share the dimension 1/s, so a dimensions-only units library happily adds a monitor's refresh rate to a radiation reading. mp-units pioneered quantity kinds: same dimension, different meaning, and mixing them does not compile. Episode 2 of the mp-units series.
The unit bug that crashed into Mars
In 1999 the Mars Climate Orbiter was lost because one team's software spoke pound-force seconds and another's expected newton seconds. mp-units, a C++ quantities library, makes that whole bug class uncompilable. First post of a series that follows the library to its C++29 standardization bid.
std::mdspan views one flat buffer as a matrix
std::mdspan is C++23's non-owning multidimensional view. It separates storage (a flat buffer you already have) from shape (extents) from indexing (a layout), so one std::vector becomes a 3x4 matrix with real m[r, c] indexing and no copy. GCC 16.1 ships it, and Mark Hoemmen's C++Now 2026 keynote is on where it and standard parallelism go next.
std::print does not tear the way std::cout does
The fixes so far needed cooperation or a lock. C++23's std::print gives per-call atomicity for free: a single print call never interleaves with another, the way printf never did and std::cout always could. But the guarantee is per-call, so a line split across two calls can still tear. Episode 4 of the concurrent I/O series.
std::flat_map is just two vectors
C++23's std::flat_map is an adaptor over a sorted vector of keys and a parallel vector of values. That buys cache-friendly lookups and near-zero memory overhead, and costs O(n) insertion and aggressive iterator invalidation. It replaces std::map, not std::unordered_map, and knowing which vector trick it is tells you exactly when to reach for it.
What reinterpret_cast doesn't do: Fertig on std::start_lifetime_as and the C++23 escape hatch
Andreas Fertig's 2026-05-18 post (re-shared on isocpp.org) makes a pointed case: reinterpret_cast and std::start_lifetime_as look interchangeable -- but only if you don't read the abstract-machine fine print. reinterpret_cast is a POINTER operation; std::start_lifetime_as is an OBJECT-LIFETIME operation. The 5-line difference between UB-then-it-works-on-my-compiler and defined-behavior.