![]() | Review waiting, please be patient.
This may take 3 months or more, since drafts are reviewed in no specific order. There are 4,822 pending submissions waiting for review.
Where to get help
How to improve a draft
You can also browse Wikipedia:Featured articles and Wikipedia:Good articles to find examples of Wikipedia's best writing on topics similar to your proposed article. Improving your odds of a speedy review To improve your odds of a faster review, tag your draft with relevant WikiProject tags using the button below. This will let reviewers know a new draft has been submitted in their area of interest. For instance, if you wrote about a female astronomer, you would want to add the Biography, Astronomy, and Women scientists tags. Editor resources
Reviewer tools
|
Reflection in C++ refers to the usage of reflective programming, introduced to the C++ programming language in C++26.1 Reflection in C++, unlike other languages like Java and C#, occurs at compile time and incurs no runtime overhead.2
Symbols in the C++ Standard Library handling reflection exist in the std::meta namespace, provided by the <meta> header.1
As of currently, GCC has support for reflection3, while support in Clang is undergoing development4 with an experimental Clang fork by Bloomberg implementing much of the specification.5
History
Until C++26, C++ was very limited in reflective capabilities. It featured type introspection via run-time type information, with a typeid operator6 for querying basic information at runtime through a type std::type_info.7 C++ also featured a dynamic_cast operator for casting a reference or pointer down to a more specific type in the class hierarchy, similar to a Java typecast.8
C++11 introduced the <type_traits> header as part of C++'s initial move towards metaprogramming. This provided class templates allowing for checking whether a type satisfied certain traits (such as std::is_class, std::is_function, etc.), however could only act on types rather than any meta-object.9 These, however, provided features to constrain templates in template metaprogramming techniques, such as with "substitution failure is not an error" (SFINAE)10, which concepts simplified further in C++20 with a cleaner syntax to express type constraints.1112
Prior to the introduction of language-level reflection to C++, many third-party libraries attempted to emulate reflection-like capabilities. Among these include Boost.Hana13 for metaprogramming, reflect-cpp14 for data serialisation, POCO C++ Libraries for Java-style class loading15 and code generation16, and Magic Enum17 for enum reflection. Qt features a meta-object compiler, qt-moc, for handling generating reflection metadata for Qt's C++ extensions.18
The original technical specification for reflection, the Reflection TS1920, was published in March of 2020 and was based on the C++20 standard. Being a type-based reflection system, it proposed an operator reflexpr() which queried a unique metadata type (i.e. reflexpr(A) and reflexpr(B) were the same if and only if A and B were the same type).21 It proposed the header <reflect> and namespace std::reflect, and classified type metadatas through concepts (such as std::reflect::Class, std::reflect::Namespace, std::reflect::Function).1920 However, later proposals suggested value-based reflections rather than type-based reflections, to allow for greater flexibility.22
Reflection, in its current form, was voted into the C++ standard in June 2025. It introduced the header <meta> and namespace std::meta. Rather than the type-based reflection seen in the Reflection TS, it introduced a value-based reflection system, where all reflection type metadatas were of a type std::meta::info, and queried by a new operator ^^. Many in the C++ Standards Committee highlighted its introduction as a major change to the language. In particular, Herb Sutter, chair of the ISO C++ Standards Committee and Hana Dusíková, assistant chair of the "Language Evolution" working group of the C++ Standards Committee, described the potential impacts for including reflection to C++ as a "whole new language."23 Sutter further described C++26 as the most 'compelling' release since C++11.24
An additional proposal was made for consteval variables, for use with compile-time constructs like info, but was not added in C++26.25
Herb Sutter additionally created a metaclass proposal building off of the features introduced in reflection, but it was not introduced in C++26.26 Code injection was also proposed for reflection, which would allow for token sequences to be injected into source code at compilation.27
Overview
Reflection in C++26 is value-based.21 It introduces a new operator ^^, called the "reflection operator"28 (colloquially called the "cat-ears operator"29), with type metadatas being represented as a type std::meta::info, usually defined as decltype(^^int).30 It further introduces a "splice specifier" [: :]31, which can be seen as the "inverse" of the reflection operator ^^, taking a metadata information and turning it back to code.1 For example, if r reflections a member named name, obj.[:r:] becomes obj.name, while if stringClass is ^^std::string, then the declaration typename [:stringClass:] name = "John Doe"s; becomes string name = "John Doe"s;.
import std;
using std::string;
using std::meta::info;
struct User {
string name;
int age;
};
int main() {
// reflect the User class's type metadata
constexpr info userClass = ^^User;
// splice [:userClass:] into User
constexpr typename [:userClass:] john {
.name = "John Doe",
.age = 20
};
std::println("The class of {} is {}", john.name, std::meta::identifier_of(userClass));
}
info is a scalar type, which defines equality and inequality, but not ordering. If it is default constructed, it produces a null reflection value, equal only to other null reflection values but no reflection values that refer to an entity. info is strictly consteval-only, meaning that it may exist only at compile-time and any expression with a consteval-only type may only be evaluated at compile-time.1
While most entities and named symbols may be reflected, including functions, classes, enums, namespaces, others such as modules, cannot.
Parameter reflection, used for reflecting parameter types and parameter names, was introduced, allowing for advanced dependency injection techniques, language bindings32, and Python-style "keyword-arguments".33
C++26 introduces "expansion statements", written as template for.34 Building off of boost::hana::for_each()'s features, this loop is processed entirely by the compiler, and unrolls the loop for each item in the collection, such as a tuple, array, class, range, or brace-delimited list of expressions.
For example, the following demonstrates the usage of a expansion statement in a mixin with the curiously recurring template pattern to generate JSON from a struct.
import std;
using std::string;
using std::string_view;
using std::meta::info;
template <typename Host>
class JsonSerializable {
protected:
JsonSerializable() = default;
public:
string toJson() const {
const Host& self = static_cast<const Host&>(*this);
string json = "{";
bool first = true;
template for (constexpr info member : std::meta::nonstatic_data_members_of(^^Host)) {
if (!first) {
json += ", ";
}
first = false;
constexpr string_view name = std::meta::identifier_of(member);
json += std::format("\"{}\": {}", name, self.[:member:]);
}
json += "}";
return json;
}
};
struct User : public JsonSerializable<User> {
string name;
int age;
bool active;
};
struct StoreProduct : public JsonSerializable<StoreProduct> {
string sku;
double price;
};
int main() {
User jane {
.name = "Jane Doe",
.age = 25,
.active = true,
};
StoreProduct mug {
.sku = "MUG-WHT-12OZ",
.price = 2.99,
};
// prints {"name": "Jane Doe", "age": 25, "active": true}
std::println("jane = {}", jane.toJson());
// prints {"sku": "MUG-WHT-12OZ", "price": 2.99}
std::println("mug = {}", mug.toJson());
}
Reflection uses exception-based error handling. C++26 introduces constexpr exceptions, allowing reflection-based exceptions to be thrown at compile-time. Functions in std::meta throw std::meta::exception, except for std::meta::define_aggregate() which causes a compilation error if invalid.35 Because std::meta::exception is primarily for handling invalid reflective operations at compile-time, in addition to the exception message, its constructor also takes a std::meta::info parameter for which metadata it failed on as well as an optional std::source_location parameter specifying the location of interest (by default, its current location).
import std;
using std::source_location;
using std::vector;
using std::meta::exception;
using std::meta::info;
consteval info memberAt(info x, size_t i, source_location where = source_location::current()) {
vector<info> members = std::meta::members_of(x);
if (i >= v.size()) {
// Note here that exception is std::meta::exception, not std::exception
throw exception(
std::format("{} is beyond the member count ({})", i, v.size()),
^^memberAt,
where
);
}
return v[i];
}
Additional features for defining static strings, objects, and arrays were introduced for allowing for compile-time strings/objects/arrays to be promoted static storage for usage at runtime.36
Annotations
Annotations allow for the addition of metadata to declarations and entities in such a way that can be read by reflection, implementing attribute-oriented programming.37 Historically, C++11 introduced attributes38, which indicated information to the compiler, but these were either standard-defined or implementation-defined39, and could not be custom-created. Additionally, reflection does not support querying attributes, and can be ignored by the compiler.
class Integer {
private:
[[no_unique_address]]
int x;
public:
[[nodiscard]]
bool isPositive() const noexcept {
if (x > 0) [[likely]] {
return true;
}
return false;
}
};
Thus, to distinguish from attributes, annotations are declared with similar syntax to attributes, but with an equals sign (=) before the annotation name. Unlike Java annotations, which have a unique syntax for declaration (@interface)40, C++ attributes may be anything (even integers, like [[=1]]), but are typically declared as struct/class to allow for customisation. Annotations may be used either with a single global object (typically used for stateless/marker annotations), or may be constructed as needed (typically used for annotations needing to carry additional information). For example, using a custom annotation, a JSON serialiser can be informed to skip sensitive fields:
import std;
using std::string;
// Define a custom attribute class
struct ExcludeAnnotation {};
// Define a global instance of the Exclude annotation
inline constexpr ExcludeAnnotation Exclude;
template <typename Host>
class JsonSerializable {
protected:
JsonSerializable() = default;
public:
string toJson() const {
const Host& self = static_cast<const Host&>(*this);
string json = "{";
bool first = true;
template for (constexpr info member : std::meta::nonstatic_data_members_of(^^Host)) {
// Additional check for the Exclude annotation
if constexpr (std::meta::has_annotation(member, Exclude) {
continue;
}
if (!first) {
json += ", ";
}
first = false;
constexpr string_view name = std::meta::identifier_of(member);
json += std::format("\"{}\": {}", name, formatValue(self.[:member:]));
}
json += "}";
return json;
}
};
struct User {
// A username field, which is public information
string username;
// A password field, which is sensitive (private) information
[[=Exclude]]
string password;
};
int main() {
User bob {
.username = "Bob123",
.password = "a0Q4}B*9^7&£",
};
// prints {"username": "Bob123"}
std::println("bob = {}", bob.toJson());
}
Another use case is command-line argument parsing; annotations may be used for parser derivation, similar to that of the clap library in Rust, using constructible annotations:4137
export module wikipedia.clap;
import std;
using std::string;
export namespace wikipedia::clap {
struct Description {
string message;
};
struct ShortName {
char c;
};
struct LongName {
string name;
};
template <typename T>
constexpr T parse(int argc, char* argv[]) {
// parse the Args struct...
}
// more stuff...
}
Then, in use:
import std;
import wikipedia.clap;
using std::string;
using wikipedia::clap::Description;
using wikipedia::clap::LongName;
using wikipedia::clap::ShortName;
struct Args {
[[=Description("Name of the person to greet")]]
[[=ShortName('n')]]
[[=LongName("name")]]
string name;
[[=Description("Number of times to greet")]]
[[=ShortName('c')]]
[[=LongName("count")]]
int count = 1;
};
int main(int argc, char* argv[]) {
Args args = wikipedia::clap::parse<Args>(argc, argv);
for (int i = 0; i < args.count; ++i) {
std::println("Hello {}", args.name);
}
}
Comparison with other languages
C++ reflection, due to its static (compile-time) nature, incurs no runtime overhead or binary size increase.1 However, this also gives it less power than the runtime reflection systems of languages like Java (java.lang.reflect) and C# (System.Reflection), which are capable of loading and inspecting entirely new code at runtime.4243 ^^T in C++ can be seen as similar to T.class in Java (which returns java.lang.Class<T>) or java.lang.Object::getClass() (which returns the wildcarded java.lang.Class<?>)44, or typeof(T) in C# (which returns System.Type)45. In Java, an attribute is declared as an interface using @interface, with additional specifiable information in java.lang.annotation.46 In C#, an attribute is any class that extends System.Attribute.47
Meanwhile, compared to procedural macros in Rust, C++'s reflection is an actual reflection system, while Rust's procedural macros primarily handle code generation, as they act over Rust syntax.48 However, Rust procedural macros also provide support for custom attributes (like C++ annotations), with the #[attr] syntax for attribute macros and #[derive(Derive)] for derive macros.49
References
References
- Wyatt Childers, Peter Dimov, Dan Katz, Barry Rezvin, Andrew Sutton, Faisal Vali, Daveed Vandevoorde (20 June 2026). "Reflection for C++". isocpp.org. WG21.
{{cite web}}: CS1 maint: multiple names: authors list (link) - Tristan Soliven (1 May 2026). "C++26 Reflection: What It Actually Changes for Large Codebases". wholetomato.com. Whole Tomato.
- GNU Project (30 April 2026). "GCC 16 Release Series Changes, New Features and Fixes". gcc.gnu.org. GNU Project.
- Vlad Serebrennikov (20 November 2025). "Dedicated meeting for C++26 reflection". discourse.llvm.org. Vlad Serebrennikov.
- Bloomberg L.P. (4 April 2026). "Clang/P2996". github.com. Bloomberg L.P.
- cppreference.com. "typeid operator". cppreference.com. cppreference.com. Retrieved 1 May 2026.
- cppreference.com. "std::type_info". cppreference.com. cppreference.com. Retrieved 1 May 2026.
- cppreference.com. "dynamic_cast conversion". cppreference.com. cppreference.com. Retrieved 1 May 2026.
- cppreference.com. "Standard library header <type_traits> (C++11)". cppreference.com. cppreference.com. Retrieved 1 May 2026.
- Vandevoorde, David; Nicolai M. Josuttis (2002). C++ Templates: The Complete Guide. Addison-Wesley Professional. ISBN 0-201-73484-2.
- cppreference.com. "Concepts library". cppreference.com. cppreference.com. Retrieved 1 May 2026.
- Fertig, Andreas (2021). Programming with C++20. Fertig Publications. p. 23. ISBN 978-3-949323-01-0.
- Boost.org (3 September 2020). "Boost Hana: Your standard library for metaprogramming - User Manual". boost.org. Boost.org.
- Patrick Urbanke (13 February 2026). "reflect-cpp, a C++20 library for fast serialization, deserialization and validation using reflection". github.com. Patrick Urbanke.
- POCO Project (16 April 2026). "Class Poco::ClassLoader". pocoproject.org. POCO Project.
- POCO Project (16 April 2026). "POCO PRO C++ Frameworks and IoT Extensions". pocoproject.org. POCO Project.
- Daniil Goncharov (13 November 2024). "magic_enum: Static reflection for enums". github.com. Daniil Goncharov.
- Qt Group (23 March 2026). "Using the Meta-Object Compiler (moc)". doc.qt.io. Qt Group.
- David Sankel (2 March 2020). "C++ Extensions for Reflection" (PDF). cplusplus.github.io. WG21.
- cppreference.com. "Extensions for reflection". cppreference.com. cppreference.com. Retrieved 1 May 2026.
- Barry Rezvin (9 June 2025). "Type-based vs Value-based Reflection". brezvin.github.io. Barry Rezvin.
- Andrew Sutton, Faisal Vali, Daveed Vandevoorde (10 August 2018). "Scalable Reflection in C++" (PDF). open-std.org. WG21.
{{cite web}}: CS1 maint: multiple names: authors list (link) - Sutter, Herb. "Trip report: June 2025 ISO C++ standards meeting (Sofia, Bulgaria)". Sutter's Mill. Retrieved 6 September 2025.
- Sutter, Herb (29 March 2026). "C++26 is done! — Trip report: March 2026 ISO C++ standards meeting (London Croydon, UK)". herbsutter.com. Retrieved 29 March 2026.
- Barry Rezvin, Peter Dimov (13 March 2025). "Consteval-only Values and Consteval Variables". open-std.org. WG21.
- Sutter, Herb (12 October 2024). "Declarative class authoring using consteval functions + reflection + generation (aka: Metaclasses for generative C++)" (PDF). open-std.org. WG21. Retrieved 14 December 2025.
- Andrei Alexandrescu, Barry Rezvin, Daveed Vandevoorde (16 July 2024). "Code Injection with Token Sequences". open-std.org. WG21.
{{cite web}}: CS1 maint: multiple names: authors list (link) - cppreference.com. "Reflection operator (since C++26)". cppreference.com. cppreference.com. Retrieved 2 May 2026.
- Herb Sutter (23 January 2026). "Reflection: C++'s Decade-Defining Rocket Engine - Herb Sutter - CppCon 2025". youtube.com. CppCon.
- GNU Compiler Collection (22 April 2026). "gcc/libstdc++-v3/include/std/meta at master". github.com. GNU Compiler Collection.
- cppreference.com. "Splice specifiers (since C++26)". cppreference.com. cppreference.com. Retrieved 2 May 2026.
- Adam Lach, Jagrut Dave (18 September 2023). "Python Bindings with Value-Based Reflection" (PDF). open-std.org. WG21.
- 20 June 2025. "Function Parameter Reflection in Reflection for C++26" (PDF). isocpp.org. WG21.
{{cite web}}: CS1 maint: numeric names: authors list (link) - Dan Katz, Andrew Sutton, Sam Goodrick, Daveed Vandevoorde, Barry Rezvin (20 June 2025). "Expansion Statements". isocpp.org. WG21.
{{cite web}}: CS1 maint: multiple names: authors list (link) - Peter Dimov, Barry Rezvin (17 June 2025). "Error Handling in Reflection". isocpp.org. WG21.
- Wyatt Childers, Peter Dimov, Barry Rezvin, Daveed Vandevoorde (20 June 2025). "define_static_{string,object,array}". isocpp.org. WG21.
{{cite web}}: CS1 maint: multiple names: authors list (link) - Wyatt Childers, Dan Katz, Barry Rezvin, Daveed Vandevoorde (19 June 2025). "Annotations for Reflection". isocpp.org. WG21.
{{cite web}}: CS1 maint: multiple names: authors list (link) - cppreference.com. "Attribute specifier sequence (since C++11)". cppreference.com. cppreference.com. Retrieved 1 May 2026.
- LLVM Developer Group (21 April 2026). "Attributes in Clang". clang.llvm.org. LLVM Developer Group.
- "Annotations". Sun Microsystems. Archived from the original on 2011-09-25. Retrieved 2011-09-30.
- Kevin Knapp (15 April 2026). "Crate clap". docs.rs. Kevin Knapp.
- Glen McCluskey (January 1998). "Using Java Reflection". oracle.com. Sun Microsystems.
- Microsoft Learn (19 March 2025). "Attributes". learn.microsoft.com. Microsoft Learn.
- Oracle Corporation (21 April 2026). "Class Object". docs.oracle.com. Java SE Documentation.
- Microsoft Learn. "Object.GetType Method". learn.microsoft.com. Microsoft Learn. Retrieved 21 April 2026.
- Oracle Corporation. "Package java.lang.annotation". docs.oracle.com. Oracle Corporation. Retrieved 1 May 2026.
- Microsoft Learn. "Attribute Class". learn.microsoft.com. Microsoft Learn. Retrieved 1 May 2026.
- The Rust Team (16 April 2026). "Procedural Macros - The Rust Reference". doc.rust-lang.org. The Rust Team.
- The Rust Team (16 April 2026). "Attributes - The Rust Reference". doc.rust-lang.org. The Rust Team.
