Extensions for reflection
The C++ Extensions for Reflection, ISO/IEC TS 23619:2021, specifies modifications to the core language and defines new components for the C++ standard library listed on this page.
The Reflection TS is based on the C++20 standard (except that the definition of concepts are specified in the style of Concepts TS ).
Core language changes
reflexpr-specifier
A
reflexpr-specifier
is of form
reflexpr
(
reflexpr-operand
)
, and specifies a meta-object type (see below).
reflexpr-operand can be one of following:
::
|
(1) | ||||||||
type-id | (2) | ||||||||
nested-name-specifier (optional) namespace-name | (3) | ||||||||
id-expression | (4) | ||||||||
(
expression
)
|
(5) | ||||||||
function-call-expression | (6) | ||||||||
functional-type-conv-expression | (7) | ||||||||
where function-call-expression is
postfix-expression
(
expression-list
(optional)
)
|
|||||||||
and functional-type-conv-expression are following sorts of expressions which perform explict cast :
simple-type-specifier
(
expression-list
(optional)
)
|
(1) | ||||||||
typename-specifier
(
expression-list
(optional)
)
|
(2) | ||||||||
simple-type-specifier braced-init-list | (3) | ||||||||
typename-specifier braced-init-list | (4) | ||||||||
The operand to the reflexpr-specifier shall be a type , namespace , enumerator , variable, data member , function parameter , captured entity , function-call-expression or functional-type-conv-expression , and parenthesized expression. reflexpr ( :: ) reflects the global namespace.
For a
reflexpr-operand
of form
(
expression
)
, the
expression
shall be a (possibly multi-parenthesized)
function-call-expression
or
functional-type-conv-expression
.
If an unparenthesized operand can be treated as either a
type-id
or a
functional-type-conv-expression
, then it is treated as a
type-id
. Parenthesizes can be used for disambiguation between function-style cast and a
type-id
. For example, given a class type
X
with default constructor,
reflexpr
(
X
(
)
)
reflects the function type
X
(
)
, and
reflexpr
(
(
X
(
)
)
)
reflects the expression
X
(
)
.
If the operand designates both an alias and a class name, the type represented by the reflexpr-specifier reflects the alias and satisfies
reflect::Alias
.
If the operand designates a name whose declaration is enclosed in a block scope and the named entity is neither captured nor a function parameter, the program is ill-formed.
Meta-object types
A
meta-object type
is an unnamed, incomplete namespace-scope class type. A type satisfies the concept
reflect::Object
if and only if it is a meta-object type. Meta-object types may satisfy other concepts, depending on the operand to
reflexpr
.
It is unspecified whether repeatedly applying
reflexpr
to the same operand yields the same type or a different type. If a meta-object type reflects an incomplete class type, certain type transformations cannot be applied.
A meta-object type allows inspection of some properties of the operand to
reflexpr
through type traits or type transformations on it.
Overload resolution
If the postfix-expression of the function-call-expression is of class type, i.e. e in the function-call-expression e ( args ) is of class type, then the user-defined conversion function of the type of the postfix-expression ( e ) shall not be used.
If postfix-expression is not of class type, it shall name a function that is the unique result of overload resolution.
struct Functor { void operator()(int) const; using fptr_t = void(*)(std::nullptr_t); operator fptr_t() const; }; using Meta0 = reflexpr(Functor{}(0)); // OK // using Meta1 = reflexpr(Functor{}(nullptr)); // error: conversion function used
An alias is a name introduced by a typedef declaration, an alias-declaration , or a using-declaration .
An entity or alias
B
is
reflection-related
to an entity or alias
A
if
-
A
andB
are the same entity or alias, -
A
is a variable or enumerator andB
is the type ofA
, -
A
is an enumeration andB
is the underlying type ofA
, -
A
is a class andB
is a member or base class ofA
, -
A
is a non-template alias that designates the entityB
, -
A
is not the global namespace andB
is an enclosing class or namespace ofA
, -
A
is the parenthesized expression (B
), -
A
is a lambda capture of the closure typeB
, -
A
is the closure type of the lambda captureB
, -
B
is the type specified by the functional-type-conv-expressionA
, -
B
is the function selected by overload resolution for a function-call-expressionA
, -
B
is the return type, a parameter type, or function type of the functionA
, or -
B
is reflection-related to an entity or aliasX
andX
is reflection-related toA
.
Reflection-relation relationship is reflexive and transitive, but not symmetric.
Informally speaking, the case that
B
is reflection-related to
A
means that
B
participates in the declaration or definition of
A
.
Zero or more successive applications of type transformations that yield meta-object types to the type denoted by a reflexpr-specifier enable inspection of entities and aliases that are reflection-related to the operand; such a meta-object type is said to reflect the respective reflection-related entity or alias.
struct X; struct B { using X = ::X; typedef X Y; }; struct D : B { using B::Y; }; // ::X, but not B::X or B::Y is reflection-related to D::Y
Miscellaneous
- An expression used as reflexpr-operand is an unevaluated expressions and potentially constant evaluated .
-
For the purpose of determination of variables
captured in a lambda expression
by a capture-default, a
reflexpr
operand is not considered to be an unevaluated operand. -
A function or variable of static
storage duration
reflected by meta-object type
T
is odr-used by the specialization std :: experimental :: reflect :: get_pointer < T > , as if by taking the address of an id-expression nominating the function or variable. - There can be more than one definition of a meta-object type, as long as all operations on this type yield the same constant expression results.
-
A type is
dependent
if it is denoted by a reflexpr-specifier, and the operand
- is a type-dependent expression or a (possibly parenthesized) functional-type-conv-expression with at least one type-dependent immediate subexpression, or
- designates a dependent type or a member of an unknown specialization or a value-dependent constant expression .
Keywords
Predefined feature testing macros
__cpp_reflection
(reflection TS)
|
a value of at least
201902
indicates that the Reflection TS is supported
(macro constant) |
Library support
Concepts
Defined in header
<experimental/reflect>
|
|
Defined in namespace
std::experimental::reflect
|
|
Defined in inline namespace
std::experimental::reflect::v1
|
|
(reflection TS)
|
specifies that a type is a meta-object type
(concept) |
(reflection TS)
|
specifies that a meta-object type is a meta-object sequence type
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a template parameter scope
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects an entity or alias with an associated (possibly empty) name
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a type alias, namespace alias, or an alias introduced by a using-declaration
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a
member-declaration
of a class
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects an enumerator
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a variable or data member
(concept) |
(reflection TS)
|
specifies that a meta-object type satisfies
RecordMember
,
Enumerator
, or
Variable
, or reflects a namespace other than the global namespace
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects an entity with a type
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a namespace
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects the global namespace
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a non-union class type
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects an enumeration type
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a class type
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a namespace, class, enumeration, function, closure type, a template parameter scope
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a type
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects an enumerator or a constexpr variable
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a direct base class obtained from
get_base_classes
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a function parameter
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a function (including constructors and destructors)
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects an expression
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a parenthesized expression
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a
function-call-expression
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a
functional-type-conv-expression
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a function (excluding constructors and destructors)
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a member function (excluding constructors and destructors)
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a special member function
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a constructor
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a destructor
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects an operator function or a conversion function
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a conversion function
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects the closure type of a non-generic lambda
(concept) |
(reflection TS)
|
specifies that a meta-object type reflects a lambda capture
(concept) |
Meta-object operations
Defined in header
<experimental/reflect>
|
|
Defined in namespace
std::experimental::reflect
|
|
Defined in inline namespace
std::experimental::reflect::v1
|
|
|
|
(reflection TS)
|
checks if two meta-object types reflect the same entity or alias
(class template) |
(reflection TS)
|
obtains the presumed line number of the declaration of the reflected entity or alias
(class template) |
(reflection TS)
|
obtains the implementation-defined column number of the declaration of the reflected entity or alias
(class template) |
(reflection TS)
|
obtains the presumed file name of the declaration of the reflected entity or alias
(class template) |
|
|
(reflection TS)
|
obtains the size of a meta-object sequence
(class template) |
(reflection TS)
|
obtains the meta-object type with specified index in a sequence
(class template) |
(reflection TS)
|
applies a template to the meta-object sequence
(class template) |
|
|
(reflection TS)
|
checks if the reflected entity or alias is unnamed
(class template) |
(reflection TS)
|
obtains the unqualified name of the reflected entity or alias
(class template) |
(reflection TS)
|
obtains the implementation-defined display name of the reflected entity or alias
(class template) |
|
|
(reflection TS)
|
obtains the meta-object type reflecting the associated entity of the reflected alias
(class template) |
|
|
(reflection TS)
|
obtains the meta-object type reflecting the type of the reflected entity or alias
(class template) |
(reflection TS)
|
obtains the type of the reflected entity or alias
(class template) |
(reflection TS)
|
checks if the meta-object type reflects an enumeration type
(class template) |
(reflection TS)
|
checks if the meta-object type reflects a union type
(class template) |
(reflection TS)
|
checks if the meta-object type reflects a non-union class type whose declaration uses
class
or
struct
respectively
(class template) |
|
|
(reflection TS)
|
obtains the meta-object type reflecting the scope of the reflected entity or alias
(class template) |
|
|
(reflection TS)
|
obtains the meta-object type reflecting the base class in the given base class relationship
(class template) |
|
|
(reflection TS)
|
checks if the reflected member or base class is public
(class template) |
(reflection TS)
|
checks if the reflected member or base class is protected
(class template) |
(reflection TS)
|
checks if the reflected member or base class is private
(class template) |
|
|
obtains a meta-object sequence type whose elements reflect public, accessible, or all data members of the reflected class
(class template) |
|
obtains a meta-object sequence type whose elements reflect public, accessible, or all member functions of the reflected class
(class template) |
|
(reflection TS)
|
obtains a meta-object sequence type whose elements reflect all constructors of the reflected class
(class template) |
(reflection TS)
|
obtains a meta-object sequence type whose elements reflect all operator functions and conversion functions declared in the reflected class
(class template) |
(reflection TS)
|
obtains the meta-object type reflecting the destructor of the reflected class
(class template) |
obtains a meta-object sequence type whose elements reflect public, accessible, or all nested type or member typedefs of the reflected class
(class template) |
|
obtains a meta-object sequence type whose elements reflect public, accessible, or all base classes of the reflected class
(class template) |
|
|
|
(reflection TS)
|
checks whether the reflected enumeration is scoped
(class template) |
(reflection TS)
|
obtains a meta-object sequence type whose elements reflects the enumerators of the reflected enumeration
(class template) |
(reflection TS)
|
obtains the meta-object type reflecting the underlying type of the reflected enumeration
(class template) |
|
|
(reflection TS)
|
obtains the value of the reflected variable which is a constant expression
(class template) |
(reflection TS)
|
checks if the variable is declared with
thread_local
(class template) |
|
|
(reflection TS)
|
checks whether the reflected parameter has a default argument
(class template) |
|
|
(reflection TS)
|
obtains a meta-object sequence type whose elements reflects the parameters of the reflected function
(class template) |
(reflection TS)
|
checks whether the parameter list of the reflected function contains an ellipsis parameter
(class template) |
(reflection TS)
|
checks whether the reflected function is non-throwing
(class template) |
(reflection TS)
|
checks whether the reflected function is deleted
(class template) |
|
|
(reflection TS)
|
checks if the reflected variable or function is constexpr
(class template) |
|
|
(reflection TS)
|
checks whether the reflected namespace or function is inline
(class template) |
|
|
(reflection TS)
|
obtains the meta-object type reflecting the unparenthesized expression of the reflected parethesized expression
(class template) |
|
|
(reflection TS)
|
obtains the meta-object type reflecting the function in the reflected
function-call-expression
(class template) |
|
|
(reflection TS)
|
obtains the meta-object type reflecting the constructor in reflected
functional-type-conv-expression
(class template) |
|
|
(reflection TS)
|
get the address of the reflected variable or function, or the pointer-to-member value to the reflected non-static member
(class template) |
|
|
checks if the reflected member function is declared with
const
,
volatile
,
&
, or
&&
qualifier respectively
(class template) |
|
(reflection TS)
|
checks if the reflected member function overrides a member function of base class
(class template) |
|
|
(reflection TS)
|
checks if the reflected class or member function is marked with
final
(class template) |
|
|
(reflection TS)
|
checks if the reflected variable is of static storage duration, or the reflected member function is static
(class template) |
|
|
(reflection TS)
|
checks if the reflected special member function is implicitly declared
(class template) |
(reflection TS)
|
checks if the reflected special member function is defaulted in its first declaration
(class template) |
|
|
(reflection TS)
|
checks if the reflected constructor or conversion function is declared with
explicit
(class template) |
|
|
(reflection TS)
|
checks if the reflected member function is virtual
(class template) |
(reflection TS)
|
checks if the reflected member function is pure virtual
(class template) |
|
|
(reflection TS)
|
obtains a meta-object sequence type whose elements reflect the captures of the reflected closure type
(class template) |
(reflection TS)
|
checks if the capture-default of the lambda expression of the reflected closure type is
=
or
&
respectively
(class template) |
(reflection TS)
|
checks if the
operator()
of the reflected closure type is declared with
const
(class template) |
|
|
(reflection TS)
|
checks if the reflected lambda capture is explicitly captured
(class template) |
(reflection TS)
|
checks if the reflected lambda capture is an init-capture
(class template) |
Library feature testing macros
Defined in header
<experimental/reflect>
|
|
__cpp_lib_reflection
(reflection TS)
|
a value of at least
201902
indicates that the support library of the Reflection TS is supported
(macro constant) |
Satisfaction of concepts
The following table lists that whether a meta-object type reflecting an operand satisfies concepts introduced by the Reflection TS.
Category |
reflexpr
operands
|
Satisfied concepts |
---|---|---|
Type | class-name designating a union |
reflect::Union
|
class-name designating a closure type |
reflect::Lambda
|
|
class-name designating a non-union class |
reflect::Record
|
|
enum-name |
reflect::Enum
|
|
template type-parameter |
reflect::Type
,
reflect::Alias
|
|
decltype-specifier |
reflect::Type
,
reflect::Alias
|
|
type-name introduced by a using-declaration |
reflect::Type
,
reflect::Alias
,
reflect::ScopedMember
|
|
any other typedef-name |
reflect::Type
,
reflect::Alias
|
|
any other type-id |
reflect::Type
|
|
Namespace | namespace-alias |
reflect::Namespace
,
reflect::Alias
|
the global namespace |
reflect::GlobalScope
|
|
any other namespace |
reflect::Namespace
|
|
Expression | the name of a data member |
reflect::Variable
|
the name of a variable |
reflect::Variable
|
|
the name of an enumerator |
reflect::Enumerator
|
|
the name of a function parameter |
reflect::FunctionParameter
|
|
the name of a captured entity |
reflect::LambdaCapture
|
|
parenthesized expression |
reflect::ParenthesizedExpression
|
|
function-call-expression |
reflect::FunctionCallExpression
|
|
functional-type-conv-expression |
reflect::FunctionalTypeConversion
|
If the operand of the form id-expression is a constant expression, the type specified by the reflexpr-specifier also satisfies
reflect::Constant
.
If the reflexpr-operand designates a class member, the type represented by the reflexpr-specifier also satisfies
reflect::RecordMember
.
See also
contains some type’s information, the class returned by the typeid operator
(class) |
|
(C++11)
|
Compile-time type information utilities |