C++26
The next major C++ standard, currently in final balloting. Static reflection transforms metaprogramming. Contracts bring Design by Contract to the language. std::execution finally lands the async story C++ has needed for a decade.
Core Language
Query and manipulate type information at compile time. Generate serializers, loggers, and boilerplate from struct definitions automatically.
#include <meta>
struct Point { int x, y; };
// Reflect on struct members
consteval std::string_view name_of(std::meta::info r) {
return std::meta::name_of(r);
}
// Generate toString() for any struct
template<typename T>
std::string to_string(const T& obj) {
std::string result = "{";
bool first = true;
[:std::meta::members_of(^T):] >> [&]<auto M>() {
if (!first) result += ", ";
result += std::string(std::meta::name_of(M));
result += ": ";
result += std::to_string(obj.[:M:]);
first = false;
};
return result + "}";
}
// to_string(Point{1, 2}) == "{x: 1, y: 2}"First-class language support for Design by Contract. [[pre:]], [[post:]], and contract_assert() with configurable violation handlers.
// Precondition — checked on entry
int sqrt_int(int n)
[[pre: n >= 0]]
[[post r: r >= 0]]
{
return static_cast<int>(std::sqrt(n));
}
// Assert — checked at point of use
void process(std::vector<int>& v, std::size_t i) {
[[assert: i < v.size()]];
v[i] *= 2;
}
// Violation handler (set globally)
// violation → calls the registered handler (default: std::terminate)Direct index into variadic parameter packs with pack...[N]. Eliminates recursive template metaprogramming for element access.
template<typename... Ts>
using first_t = Ts...[0]; // type indexing
template<typename... Ts>
auto get_first(Ts... args) {
return args...[0]; // value indexing
}
template<std::size_t I, typename... Ts>
auto get(Ts... args) {
return args...[I]; // runtime-index (I must be constexpr)
}
first_t<int, double, char> x = 42; // int
auto val = get<2>(10, 20.0, 'a'); // 'a'Include binary files (images, shaders, certificates) directly as data arrays. Replaces xxd-generated headers.
// icon.png included as a byte sequence
constexpr std::uint8_t icon_data[] = {
#embed "icon.png"
};
// With limit — first 4 bytes only
constexpr std::uint8_t header[] = {
#embed "file.bin" limit(4)
};
// Is the resource non-empty?
#if __has_embed("resource.bin")
// ...
#endifLibrary
A unified model for async work: structured concurrency, cancellation, and scheduler abstraction. The async/await that C++ deserves.
#include <execution>
namespace ex = std::execution;
// Describe async work as a pipeline of senders
auto work = ex::just(42)
| ex::then([](int n) { return n * 2; })
| ex::then([](int n) { return std::to_string(n); });
// Schedule on a thread pool
ex::thread_pool pool{4};
auto result = ex::sync_wait(
ex::on(pool.get_scheduler(), std::move(work))
);
// result == "84"First-class portable SIMD types that map to hardware (SSE, AVX, NEON). Write vectorized code once, run everywhere.
#include <simd>
namespace stdx = std::experimental;
// Process 4 floats at once (maps to SSE/NEON)
void scale(std::span<float> data, float factor) {
using V = stdx::native_simd<float>;
std::size_t i = 0;
for (; i + V::size() <= data.size(); i += V::size()) {
V v{data.data() + i, stdx::element_aligned};
v *= factor;
v.copy_to(data.data() + i, stdx::element_aligned);
}
for (; i < data.size(); ++i)
data[i] *= factor; // scalar tail
}A vector with compile-time capacity cap stored on the stack. No heap allocation, no dynamic capacity. The std version of boost::static_vector.
#include <inplace_vector>
// Stack-allocated vector with max 8 elements
std::inplace_vector<int, 8> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
// Has vector-like API
std::ranges::sort(v);
// No heap, no allocator, fits in stack framestd::format gains support for formatting ranges, tuples, and pairs. Write {v} to format a vector directly.
#include <format>
#include <vector>
#include <map>
std::vector<int> v{1, 2, 3, 4};
std::println("{}", v); // [1, 2, 3, 4]
std::println("{:n}", v); // 1, 2, 3, 4 (no brackets)
std::map<std::string, int> m{{"a", 1}, {"b", 2}};
std::println("{}", m); // {"a": 1, "b": 2}
std::tuple<int, double, std::string> t{1, 2.5, "hi"};
std::println("{}", t); // (1, 2.5, hi)