Extensions for reflection
ObjectObjectSequenceNamedAliasTypeScopeMemberRecordMember and BaseRecordEnumVariableFunctionParameterCallableVariable and CallableNamespace and CallableParenthesizedExpressionFunctionCallExpressionFunctionalConversionVariable and FunctionMemberFunctionRecord and MemberFunctionVariable and MemberFunctionLambdaLambdaCaptureThe 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
-
AandBare the same entity or alias, -
Ais a variable or enumerator andBis the type ofA, -
Ais an enumeration andBis the underlying type ofA, -
Ais a class andBis a member or base class ofA, -
Ais a non-template alias that designates the entityB, -
Ais not the global namespace andBis an enclosing class or namespace ofA, -
Ais the parenthesized expression (B), -
Ais a lambda capture of the closure typeB, -
Ais the closure type of the lambda captureB, -
Bis the type specified by the functional-type-conv-expressionA, -
Bis the function selected by overload resolution for a function-call-expressionA, -
Bis the return type, a parameter type, or function type of the functionA, or -
Bis reflection-related to an entity or aliasXandXis 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
reflexproperand is not considered to be an unevaluated operand. - A function or variable of static storage duration reflected by meta-object type
Tis 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.