Daniel Lemire is a software performance expert. He ranks among the top 2% of scientists globally (Stanford/Elsevier 2025) and is one of GitHub’s top 1000 most followed developers.
Recently he wrote a blog post entitled Discover C++26’s compile-time reflection. Indeed, Java, C#, and indeed Python fans will be delighted: C++26 is getting compile-time reflection – and that’s a big deal.
Herb Sutter has confirmed it: C++26 will ship with compile-time reflection. This is one of the most important upgrades to C++ in decades.
What is reflection (in plain terms)?
Reflection means code that can see and reason about itself.
Given a type, you can:
- List its data members
- Get their names and types
- Generate code based on that structure
Languages like Java, C#, and Python have had reflection forever — but usually at runtime, with performance and safety costs.
C++ is doing something different.
What makes C++ reflection special?
C++26 reflection is compile-time.
That means:
- No runtime overhead
- No stringly-typed hacks
- Fully type-checked
- Optimized away by the compiler
You’re not inspecting objects while running — you’re generating code while compiling.
Why should C++ programmers care?
Because it kills boilerplate.
Example: JSON serialization
Today, mapping a struct to JSON means:
- Writing manual serializers
- Maintaining them forever
- Debugging mismatches
With compile-time reflection, libraries like simdjson can do this automatically:
struct kid {
int age;
std::string name;
std::vector<std::string> toys;
};
kid k{12, "John", {"car", "ball"}};
simdjson::to_json(k);
// {"age":12,"name":"John","toys":["car","ball"]}
kid k2 = doc.get<kid>();
No macros. No annotations. No runtime reflection tax.
The mapping is generated at compile time and heavily optimized.
Example: Object → SQL mapping (ORM without the pain)
Take a simple struct:
struct User {
int id;
std::string name;
double balance;
private:
int secret; // ignored
};
You want:
INSERT INTO tbl (id, name, balance)
VALUES (0, '', 0.000000);
With compile-time reflection, this becomes:
generate_sql_insert(user, "tbl");
What happens under the hood?
At compile time, the code:
- Enumerates all public data members
- Extracts their names
- Generates the column list as a compile-time string
- Emits efficient formatting code for values
The SQL string is largely precomputed during compilation.
Why this matters architecturally
This unlocks a new style of C++ programming:
- Zero-boilerplate serialization
- Type-safe code generation
- One implementation, reused everywhere
- Library-level correctness instead of copy-paste bugs
You write the hard logic once, test it thoroughly, and every type benefits.
“But the code looks scary…”
Yes — reflection syntax is new and template-heavy.
But:
- Most users won’t write this code
- Library authors will
- End users get clean, simple APIs
Exactly like STL, ranges, or allocators: scary inside, elegant outside.
Bottom line
C++26 compile-time reflection means:
- Less glue code
- Fewer macros
- Better performance
- More correctness
- Cleaner APIs
In the next few years, expect:
- Simpler serializers
- Better ORMs
- Smarter bindings
- Safer metaprogramming
This is C++ doubling down on what it does best: abstraction without overhead.
If you care about modern C++ design — this is one of the biggest wins coming your way.
For details, read Daniel’s post.
