Welcome to v1.0 of the meta::[[verse]]!

# Slide 1
# Slide 2
- C++ Software Engineer, OS Internals, Microsoft
- ISO C++ foundation and Boost foundation board member
- An active member of the ISO C++ Committee
- Israeli National Body Chair
- Library Evolution Work Group Chair
Inbal Levi

https://slides.com/inballevi/welcome-to-v1-0-of-the-meta-verse-pure-virtual/
Reflection in C++
# Slide 3
- The ability of software to expose its internal structure
-
Static reflection - compiler exposes structure at compile time
- Disclaimers:
- It's possible to "carry" the data into the runtime...
- But may introduce performance, security, or other issues
- This is out of scope for this talk (and for C++26, as of now)
This Talk
# Slide 4
- Part I: Intro to reflection:
- A brief history of "Reflection" proposals in C++
- Latest proposal: "P2996: Reflection for C++26"
- The complexity of reflection
- Part II: Impact on our code bases
- Reflection-based libraries
- What's next?
(*) Examples from or derive from P2996, or EDG's implementation
# Slide 5
2015
Boost.Hana
(Louis Dionne)
Template metaprog. lib
A Brief History
# Slide 6
A Brief History
Typefull
vs.
Monotype
Type based
vs.
Value based
meta objects
# Slide 7
A Brief History
# Slide 8
What do I mean by "Reflection"?
// Lib.hpp
class LibType : public BaseOne, public BaseTwo
{
int a;
double b;
};
P2996
// main.cpp
#include <meta>
#include "Lib.hpp"
int main()
{
constexpr std::meta::info refexpr = ^^LibType;
constexpr auto res = std::meta::bases_of(refexpr)[0];
}
https://godbolt.org/z/WxdvKdcMY
# Slide 9
P2996: Reflection for C++26
P2996
-
Reflection Operator:
^^
-
Splicers: [
:
…:]
-
std::meta::info
-
Metafunctions
8. define_aggregate (inject)
-
Name & Location:
3. Template Queries:
-
identifier_of
-
display_string_of
-
source_location_of
-
template_of
-
template_arguments_of
9. Data Layout:
4. Member Queries:
-
offset_of -> member_offset
-
size_of
-
alignment_of
-
bit_size_of
2. Type Queries:
-
members_of, bases_of
-
(non)static_data_members_of
-
enumerators_of
-
type_of
-
parent_of
-
dealias
-
Access modifiers: is_public, is_protected, is_private
-
Inheritance: is_virtual, is_pure_virtual, is_override, ...
-
Encapsulation: is_class_member, is_namespace_member, is_explicit, is_deleted, ...
-
Advanced Type Queries: is_complete_type, is_template, is_special_member, ...
10. (+) Type Traits
(+ Other Type Predicates)
5. substitute (template)
6. extract<T>(info) (constexpr not required)
7. reflect_x (extended)
-
reflect_value
-
reflect_object
-
reflect_function
auto rexpr = ^ int;
# Slide 10
The Reflection Operator (^^) (Lift)
P2996
AKA Unibrow

^
auto rexpr = ^^int;
# Slide 11
The Reflection Operator (^^) (Lift)
- Shifts expressions into a "meta" - "reflection info" object
- Object can then to be used as input to reflection utilities
error: meta type variables must be constexpr
constexpr auto rexpr = ^^int;
P2996
# Slide 12
Splicers
- Splice extract the C++ expression back from "meta::info"...
- ...To be then used regularly to write the C++ program
constexpr auto rexpr = ^^int;
typename[:rexpr:] a = 42;
What are you?
rexpr
meta::info obj, contains info on "int" type
typename[:rexpr:]
int
P2996
* More about the typename in P2996/[dcl.type.splice]
# Slide 13
P2996: Reflection for C++26
P2996
-
Reflection Operator: ^^
-
Splicers: [
:
…:]
-
std::meta::info
-
Metafunctions
8. define_aggregate (inject)
-
Name & Location:
3. Template Queries:
-
identifier_of
-
display_string_of
-
source_location_of
-
template_of
-
template_arguments_of
9. Data Layout:
4. Member Queries:
-
offset_of -> member_offset
-
size_of
-
alignment_of
-
bit_size_of
2. Type Queries:
-
members_of, bases_of
-
(non)static_data_members_of
-
enumerators_of
-
type_of
-
parent_of
-
dealias
-
Access modifiers: is_public, is_protected, is_private
-
Inheritance: is_virtual, is_pure_virtual, is_override, ...
-
Encapsulation: is_class_member, is_namespace_member, is_explicit, is_deleted, ...
-
Advanced Type Queries: is_complete_type, is_template, is_special_member, ...
10. (+) Type Traits
(+ Other Type Predicates)
5. substitute (template)
6. extract<T>(info) (constexpr not required)
7. reflect_x (extended)
-
reflect_value
-
reflect_object
-
reflect_function
# Slide 14
std::meta::info

From: "Let's talk about abstraction layers"
P2996
# Slide 15
std::meta::info
int a = 42;
constexpr auto b = ^^a;
std::cout << [:b:] << "\n"; // OK
std::cout << [:^^(a*2):] << "\n"; // Error
constexpr int a = 42;
constexpr auto b = ^^a;
std::cout << [:b:] << "\n"; // OK
std::cout << [:^^(a*2):] << "\n"; // OK
P2996
Represents:
- Type and type alias
- Function or member function
- Variable, static data member, or structured binding
- Non-static data member
- Enumerators
- Object that is a permitted result of a constant expression
- Value with structural type that is a permitted result of a const evaluation
- Template
- Namespaces, namespace alias
# Slide 16
P2996: Reflection for C++26
-
Reflection Operator: ^^
-
Splicers: [
:
…:]
-
std::meta::info
-
Metafunctions
P2996
8. define_aggregate (inject)
-
Name & Location:
3. Template Queries:
-
identifier_of
-
display_string_of
-
source_location_of
-
template_of
-
template_arguments_of
9. Data Layout:
4. Member Queries:
-
offset_of -> member_offset
-
size_of
-
alignment_of
-
bit_size_of
2. Type Queries:
-
members_of, bases_of
-
(non)static_data_members_of
-
enumerators_of
-
type_of
-
parent_of
-
dealias
-
Access modifiers: is_public, is_protected, is_private
-
Inheritance: is_virtual, is_pure_virtual, is_override, ...
-
Encapsulation: is_class_member, is_namespace_member, is_explicit, is_deleted, ...
-
Advanced Type Queries: is_complete_type, is_template, is_special_member, ...
10. (+) Type Traits
(+ Other Type Predicates)
5. substitute (template)
6. extract<T>(info) (constexpr not required)
7. reflect_x (extended)
-
reflect_value
-
reflect_object
-
reflect_function
# Slide 17
Metafunctions
constexpr auto a = 42;
std::cout << meta::name_of(^^a) << "\n";
All* the metafunctions accept "info" and return:
- string_view (e.g. identifier_of)
- std::meta::info (e.g. type_of)
- vector<std::meta::info> (e.g. bases_of)
- bool (e.g. is_concept)
- size_t (e.g. alignment_of)
- T (e.g. extract(info))
- source_location, member_offset (e.g. offset_of)
* Besides "reflect_value/object/function", which accepts type T
https://godbolt.org/z/9YW4bWGM7
constexpr auto a = 42;
std::cout << meta::identifier_of(^^a) << "\n";
P2996
# Slide 18
std::meta::info
#include <iostream>
#include <experimental/meta>
class R;
constexpr std::meta::info res1 = ^^R;
constexpr auto print1 = std::meta::
is_complete_type(res1); // (1)
class R {
int a;
};
constexpr std::meta::info res2 = ^^R;
constexpr auto print2 = std::meta::
is_complete_type(res2); // (2)
constexpr auto print3 = std::meta::
is_complete_type(res1); // (3)
int main()
{
std::cout << "Res: " << print1 << "\n"; // (1)
std::cout << "Res: " << print2 << "\n"; // (2)
std::cout << "Res: " << print3 << "\n"; // (3)
}
https://godbolt.org/z/cafxMPo4o

Complexity of Reflection
# Slide 19
Type Traits
- Two types of "Type Traits":
- Query the type
- Modify the type
- P2996 proposes the first type (e.g. is_nothrow_swappable)
- Interesting functionality available by the second type
- ...But this is more challenging, as it interferes with the compiler's representation of the program
Complexity of Reflection
# Slide 20
- Interaction between library code and user(*) code
int main()
{
type.[:get_member_i(0):] = 1;
type.[:get_member_i(1):] = 1;
type.[:member_named("pub"):] = 2;
type.[:member_named("prv"):] = 2;
}
Library Code
User(*) Code
Reflection as Customization

class LibType {
public:
int pub;
private:
int prv;
public:
void Print();
};
Complexity of Reflection
# Slide 21
Reflection Logger
#include <string>
#include <experimental/meta>
consteval bool LogMembers(std::meta::info type)
{
// Verify type is a class/struct
// Ignore usecase of unnamed members (union/struct etc.)
std::__report_constexpr_value(identifier_of(type).data());
for (auto r : nonstatic_data_members_of(type))
{
std::__report_constexpr_value("\n\tmember:");
std::__report_constexpr_value(identifier_of(r).data());
}
return true;
}
// User code
struct Student
{
std::string name;
int id;
};
static_assert(LogMembers(^^Student));
Reflection-Based Library

Based on example from EDG's CE implementation
https://godbolt.org/z/Yddfxdq8j

# Slide 22
Detour: But what about AI?
Summary
Generate "MyTypeSerializer" class in a header (you can add .cpp file if needed), based on "MyType.h" which provide "serialize" and "deserialize" methods for "MyType", turning it into bytes buffer and back into a "MyType" class.
# Slide 23
Detour: But what about AI?
Summary

# Slide 24
Detour: But what about AI?
Summary

# Slide 25
Detour: But what about AI?
- LLMs are trained on data to create weights
- Algorithm aims for the "most fitting" result
- There's non-determinism inherently in the process
- Definetly with new models / versions
Summary
(Disclaimer: as of now...)
No guarantees between executions
# Slide 26
Detour: But what about "Rust"?
Rust's toolkit:
- "macros" - variadic, used as templates, expend pre-compiler
- "syn" - library for injecting tokens into the AST
- "procedural macro" - used to process AST into AST
Summary
- Apr 2023: a-plan-for-generic-compile-time-introspection-in-rust
- Jul 2024: First-class CT type manipulation: rfcs#3669
- March 2025: Reflect lib (source, crate)
C++ | Rust | |
---|---|---|
Approach | Functions / traits | Token manipulation |
Failure Outcome | Ill-formed / Compile | Compile |
Error indication | constexpr exception | Runtime / tests |
# Slide 27
What should we expect from "reflection libraries"?
Guarantees we do not provide:
The outcome of "breaking the contract":
- The outcome of failures:
- Program is ill-formed (fails to compile)
- Program contains UB (undefined behavior)
- Errors at compile time:
- Should indicate to "reflection" stage (NOT "old" compilation)
- Throw constexpr exceptions (Thanks to Hana Dusíková!)
- Warnings: Which level of feedback is given to correct mistakes?
Summary
- No compatibility between standard versions
- No backward compatibility for source code
- No guarantees for existing code
# Slide 28
Summary
Which "reflection libs" should go into the standard library?
Would love your input!
- P3157R0: Generative Extensions (...) (Andrei Alexandrescu, Bryce Lelbach, Michael Garland)
- P3095R0: ABI comparison with reflection (Saksham Sharma)
- P2996's Implementation (Bloomberg)
- Comparing AI models (suggested uses)
- ACCU 2025: Learning to Stop Writing Code (Daisy Hollman)
More info:
- A brief history of "Reflection" proposals in C++
- Latest proposal: "P2996: Reflection for C++26"
- The complexity of reflection
- Reflection-based libraries
- What's next?
Summary
# Slide 29
Thank you!
Inbal Levi
sinbal2lextra@gmail.com
linkedin.com/in/inballevi/
Thank you!
Stay in touch!
Thanks to:
- CoreC++ user group
- Hana Dusíková (SG7 chair)
- Matus Chochlik
- David Sankel
- Corentin Jabot
- Lewis Baker
- Adi Shavit
Thank you for being passionate about C++!
-
Reflection Papers' authors!
Wyatt Childers, Peter Dimov, Dan Katz, Barry Revzin, Andrew Sutton, Faisal Vali, Daveed Vandevoorde, Matus Chochlik, Herb Sutter, Bjarne Stroustrup, David Sankel, Axel Naumann, Andrei Alexandrescu, Bryce Lelbach, Michael Garland, Louis Dionne, Adam Lach, Jagrut Dave, Walter Genovese, Saksham Sharma

Welcome to v1.0 of the meta::[[verse]] - Pure Virtual
By Inbal Levi
Welcome to v1.0 of the meta::[[verse]] - Pure Virtual
- 177