Extensions for reflection
Object
ObjectSequence
Named
Alias
Type
ScopeMember
RecordMember
and Base
Record
Enum
Variable
FunctionParameter
Callable
Variable
and Callable
Namespace
and Callable
ParenthesizedExpression
FunctionCallExpression
FunctionalConversion
Variable
and Function
MemberFunction
Record
and MemberFunction
Variable
and MemberFunction
Lambda
LambdaCapture
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).
Contents
- 1 Core language changes
- 2 Library support
- 2.1 Concepts
- 2.2 Meta-object operations
- 2.2.1 Object operations
- 2.2.2 ObjectSequence operations
- 2.2.3 Named operations
- 2.2.4 Alias operations
- 2.2.5 Type operations
- 2.2.6 ScopeMember operations
- 2.2.7 Base operations
- 2.2.8 RecordMember and Base operations
- 2.2.9 Record operations
- 2.2.10 Enum operations
- 2.2.11 Variable operations
- 2.2.12 FunctionParameter operations
- 2.2.13 Callable operations
- 2.2.14 Variable and Callable operations
- 2.2.15 Namespace and Callable operations
- 2.2.16 ParenthesizedExpression operations
- 2.2.17 FunctionCallExpression operations
- 2.2.18 FunctionalTypeConversion operations
- 2.2.19 Variable and Function operations
- 2.2.20 MemberFunction operations
- 2.2.21 Record and MemberFunction operations
- 2.2.22 Variable and MemberFunction operations
- 2.2.23 SpecialMemberFunction operations
- 2.2.24 Constructor and ConversionOperator operations
- 2.2.25 MemberFunction and Destructor operations
- 2.2.26 Lambda operations
- 2.2.27 LambdaCapture operations
- 2.3 Library feature testing macros
- 2.4 Satisfaction of concepts
- 3 See also
[edit] Core language changes
[edit] 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)
(
expression )
(5)
where function-call-expression is
(
expression-list(optional) )
and functional-type-conv-expression are following sorts of expressions which perform explict cast:
(
expression-list(optional) )
(1)
(
expression-list(optional) )
(2)
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.
[edit] 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.
[edit] 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
[edit]
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
[edit] 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.
[edit] Keywords
[edit] Predefined feature testing macros
(macro constant)
[edit] Library support
[edit] Concepts
<experimental/reflect>
std::experimental::reflect
std::experimental::reflect::v1
(concept)
(concept)
(concept)
(concept)
(concept)
(concept)
RecordMember
, Enumerator
, or Variable
, or reflects a namespace other than the global namespace (concept)
(concept)
(concept)
(concept)
get_base_classes
(concept)
(concept)
(concept)
(concept)
(concept)
(concept)
(concept)
(concept)
(concept)
(concept)
(concept)
(concept)
[edit] Meta-object operations
<experimental/reflect>
std::experimental::reflect
std::experimental::reflect::v1
Object
operations
(class template)
(class template)
(class template)
(class template)
ObjectSequence
operations
(class template)
Named
operations
(class template)
(class template)
Alias
operations
(class template)
Type
operations
(class template)
(class template)
(class template)
(class template)
ScopeMember
operations
(class template)
Base
operations
(class template)
RecordMember
and Base
operations
(class template)
Record
operations
(class template)
(class template)
(class template)
(class template)
(class template)
(class template)
(class template)
Enum
operations
(class template)
(class template)
Variable
operations
(class template)
(class template)
FunctionParameter
operations
(class template)
Callable
operations
(class template)
(class template)
Variable
and Callable
operations
(class template)
Namespace
and Callable
operations
(class template)
ParenthesizedExpression
operations
(class template)
FunctionCallExpression
operations
(class template)
FunctionalTypeConversion
operations
(class template)
Variable
and Function
operations
(class template)
MemberFunction
operations
(class template)
(class template)
Record
and MemberFunction
operations
(class template)
Variable
and MemberFunction
operations
(class template)
SpecialMemberFunction
operations
(class template)
(class template)
Constructor
and ConversionOperator
operations
(class template)
MemberFunction
and Destructor
operations
(class template)
Lambda
operations
(class template)
=
or &
respectively (class template)
operator()
of the reflected closure type is declared with const (class template)
LambdaCapture
operations
(class template)
(class template)
[edit] Library feature testing macros
<experimental/reflect>
(macro constant)
[edit] 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
.