cpp26-reflection
Part of the wro.cpp cpp26-reflection series — 18 of 25 posts published so far.
-
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.
-
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.
-
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.
-
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.
-
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.
-
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.
-
Deriving equality, hashing, and ordering from structure
C++20 gave us `= default` for operator== and <=>. Reflection lets us do the same for hashing, plus go beyond default: include/exclude fields, custom combinators, floating-point tolerances — all declarative.
-
A 40-line JSON serializer with reflection
Walking a struct and emitting JSON: the naive but complete version. About forty lines, no macros, no external codegen. The foundation of the reflect_json library.
-
Annotations: tag-driven serialization comes to C++
P3394 brings serde-style and Jackson-style attribute programming to C++: rename, skip, skip_if_empty, rename_all — all as plain user-defined values queryable by reflection.
-
Deserialization and std::expected: completing the round-trip
Parse JSON into a typed C++ struct with precise per-field error reporting via std::expected. Reflection + template for + annotations — the same machinery, just running the other way.
-
One codegen, many wire formats
JSON, YAML, XML, TOML, MessagePack — all from the same annotated struct. Factor format-specific syntax into a policy object, share the reflection walk, ship N formats for the cost of one.
-
Clap for C++: turning structs into command-line parsers
Rust's clap-derive in C++: declare a struct, get a working argv parser with --flags, -short options, help text, subcommands. One attribute per field, zero manual dispatch.
-
A tiny ORM: struct to SQL via reflection
Diesel / Entity Framework ergonomics in C++: annotate a struct, generate CREATE TABLE, SELECT, INSERT, UPDATE, and a row-to-struct binder. No codegen tool, no intrusive macros.
-
Autowired dependency injection: no container, just reflection
Spring's and .NET's DI containers, reimplemented as a 60-line C++26 library. Reflect constructor parameters, resolve them from a type registry, compose.
-
Auto-generated mocks from interfaces
Mockito and Moq in C++: point a library at an abstract base class and get a mock that records calls and lets you program return values. No per-method MOCK_METHOD boilerplate.
-
define_aggregate: synthesising types at compile time
TypeScript's Pick, Omit, and Partial have direct C++26 equivalents. define_aggregate lets you construct a new type from a list of member specs — opening up type-level programming that was previously pure metaprogramming wizardry.
-
Replacing Qt's MOC with reflection
Qt's Meta-Object Compiler parses Q_OBJECT/Q_PROPERTY declarations and emits glue code. With C++26 reflection, Q_PROPERTY-equivalent becomes a library pattern — no external compiler, no generated files.
-
Reflection across languages: C++26 vs Rust, C#, Java, TypeScript, Go, Python
Capstone: the canonical reflection tasks — serialize, enum↔string, CLI parsing, ORM row binding — side by side in seven mainstream languages. Where C++ lands, and what the uniquely-C++ angle actually gives you.