Namespaces
Variants
Views
Actions

Extensions for reflection

From cppreference.com
< cpp‎ | experimental
Revision as of 09:21, 11 February 2021 by Fruderica (Talk | contribs)

The C++ Extensions for Reflection, ISO/IEC DTS 23619, 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++14 standard as modified by the Concepts TS.

Contents

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) ) (1)

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, structured binding, data member, function parameter, captured entity, function-call-expression or functionaltype-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 a 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().

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 reflects, 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 is of class type in the function-call-expression e(args), then the user-defined conversion function of the type of the postfix-expression (e) shall not be used. postfix-expression shall name a function that is the unique result of overload resolution if it is not of class type.

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

Reflection-related

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

  1. A and B are the same entity or alias,
  2. A is a variable or enumerator and B is the type of A,
  3. A is an enumeration and B is the underlying type of A,
  4. A is a class and B is a member or base class of A,
  5. A is a non-template alias that designates the entity B,
  6. A is not the global namespace and B is an enclosing class or namespace of A,
  7. A is the parenthesized expression ( B ),
  8. A is a lambda capture of the closure type B,
  9. A is the closure type of the lambda capture B,
  10. B is the type specified by the functional-type-conv-expression A,
  11. B is the function selected by overload resolution for a function-call-expression A,
  12. B is the return type, a parameter type, or function type of the function A, or
  13. B is reflection-related to an entity or alias X and X is reflection-related to A.

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

Keywords

reflexpr

Predefined feature testing macros

__cpp_reflection
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
Meta-object operations
Defined in header <experimental/reflect>
Defined in namespace std::experimental::reflect
Defined in inline namespace std::experimental::reflect::v1
Library feature testing macros
Defined in header <experimental/reflect>
__cpp_lib_reflection
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
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

See also

contains some type’s information, the class returned by the typeid operator
(class) [edit]
Compile-time type information utilities[edit]