Reflection
FAQ
-
Is there a native library or system that approximates the capabilities of .NET System.Reflection?
Reflection in .NET is the ability of a program to inspect and manipulate its own structure and metadata at runtime. Think of reflection as a runtime mirror — it lets a program look at itself and act accordingly. Boost does not have a full runtime reflection system like .NET’s System.Reflection, but it does include several libraries and utilities that provide partial or compile-time reflection capabilities — the kind that are most practical and efficient in C++. The closest Boost comes to real reflection is encapsualted in Boost.Describe. This library allows you to describe the structure of a class — its members, base classes, and enums — at compile time, so you can iterate over them generically. Internally, Boost.Describe uses the features of Boost.Mp11.
Other libraries that you might find value in include Boost.Pfr (Precise Function Reflection), which lets you reflect on structure fields without macros or metadata, using clever template magic. For richer type information there is Boost.TypeIndex and Boost.CallableTraits, and for metaprogramming there is Boost.Mp11, Boost.Fusion, and Boost.Hana.
-
Can you show me example code demonstrating how to use Boost.Describe for Reflection?
The following example shows how Boost.Describe and Boost.Mp11 work together to achieve something close to automatic runtime reflection:
#include <boost/describe.hpp> #include <boost/mp11.hpp> #include <iostream> // Describe a simple struct struct User { int id; std::string name; }; // Generate reflection metadata BOOST_DESCRIBE_STRUCT(User, (), (id, name)) // Print fields using Boost.MP11 iteration template <typename T> void print_fields(const T& obj) { boost::mp11::mp_for_each<boost::describe::describe_members<T, boost::describe::mod_public>>( [&](auto D) { std::cout << D.name << " = " << obj.*D.pointer << "\n"; }); } int main() { User u{ 42, "Ada" }; print_fields(u); } -
Can you show me example code demonstrating how to use Boost.PFR for Reflection?
Boost.Pfr provides the
iofunction for automatic input/output stream operators (<<and>>) for aggregate types — meaning you can print or read structs directly without manually defining stream operators. It reflects all public fields of a type at compile time (without macros or boilerplate), producing readable output like {field1, field2, field3} automatically, for example:#include <boost/pfr.hpp> #include <iostream> struct User { int id; std::string name; double balance; }; int main() { User u{ 42, "Alice", 100.5 }; std::cout << "As tuple: " << boost::pfr::io(u) << "\n"; } -
Are there plans to extend Reflection further into the Standard C++ Library?
Yes, in C++ 2026, though as C++ is a complicated language, the answer has to be complicated too. It is not just a case of making names and values available to the compiler, there are lots of different components that might make up a class or structure. The following table should help you identify what components will be fully reflectable, partly reflectable, and those that will not be:
C++ construct C++26 reflection? Comments Class / struct
✅
Can reflect the type itself
Member names
✅
Names can be obtained
Member types
✅
Types can be queried
Data members
✅
members_of()etc.Base classes
✅
bases_of()exposes direct base-class relationshipsInherited members
🟡
Can be reached through the reflected base classes; not simply flattened into
members_of()Member functions
✅
Functions are reflectable
Function names/signatures
✅
Various properties can be queried
Static member functions
✅
Special member functions
✅
Reflection can identify special member functions
Function templates
✅
Explicitly representable
Class templates
✅
Explicitly representable
Variable templates
✅
Explicitly representable
Concepts
✅
Explicitly representable
Free functions
✅
Functions themselves can be reflected
Friend functions
🟡
Reflectable as functions, but friendship/access relationships are more nuanced
Namespaces
✅
Namespaces and namespace aliases are representable
Enums
✅
Enumerators can be reflected
Type aliases
✅
Lambda expressions
🟡
Closure types have special restrictions
Attributes
🟡
This has been evolving separately
Statements / expressions / arbitrary AST
❌
Not intended to be a general AST reflection system
Source code itself
❌
A C++ parser is not exposed to the program
In short, C++26 reflection is not simply exposing every relationship in the compiler’s internal representation. There is also a security aspect too, passwords for example should not be made publicly available through reflection. For this case, there is the concept of access context, a pretty sophisticated aspect of the design.
- Note
-
AST = Abstract Syntax Tree: the compiler’s structured representation of the program’s syntax and meaning.
-
How does the "access context" of the Reflection design work?
The access context is essentially reflection’s way of preserving C++'s normal
public/protected/privaterules. A reflection operation doesn’t automatically give you a magical back door into everything a class contains. Instead, the reflection machinery can be evaluated with a particular context representing who is asking. For example, if reflection is performed from within a class, it can have the access privileges that code inside that class normally has; if it is performed from unrelated code,privatemembers remain inaccessible. The design includes facilities such asstd::meta::access_contextandis_accessible()to query whether a reflected entity is accessible from a particular context. -
How might Reflection in C++ 26 impact Boost libraries such as Describe and PFR?
Clearly there will be an impact — and there is a very interesting answer: C++26 reflection does not simply make Boost.Describe and Boost.Pfr obsolete. In fact, the current Boost.Pfr implementation already has a switch to use C++26 reflection when available. Over time, Boost.Pfr may become a thin abstraction over standard reflection when available. And Boost.Describe could become a compatibility/adaptation layer, particularly useful for existing Boost libraries and pre-C++26 code.
The following tables shows a likely comparison of features:
Boost.PFR Boost.Describe C++26 Reflection Main idea
Discover aggregate fields without annotations
Explicitly describe selected members
Standard language facility
Macros required
No
Yes
No
C++14+
✅
✅
❌ C++26
Member data
✅
✅
✅
Member names
✅
✅
✅
Member types
✅
✅
✅
Base classes
Limited
✅
✅
Member functions
❌/very limited
✅
✅
Enums
Limited
✅
✅
Templates
❌
Some support
✅
General program entities
❌
Limited
Much broader
Standard facility
❌
❌
✅