Расширения для рефлексии
Расширения C++ для Рефлексии, ISO/IEC ТС 23619:2021, определяют модификации ядра языка и определяют новые компоненты для стандартной библиотеки C++, перечисленные на этой странице.
ТС Рефлексии основана на стандарте C++20 (за исключением того, что определение концептов указано в стиле ТС Концептов).
[править] Изменения ядра языка
[править] спецификатор reflexpr
Спецификатор reflexpr имеет форму reflexpr
(
reflexpr-операнд )
, и определяет метаобъектный тип (смотрите ниже).
reflexpr-операнд может быть одним из следующего:
::
|
(1) | ||||||||
идентификатор-типа | (2) | ||||||||
вложенный-спецификатор-имени(необязательно) имя-пространства-имён | (3) | ||||||||
идентификатор-выражения | (4) | ||||||||
( выражение )
|
(5) | ||||||||
выражение-вызова-функции | (6) | ||||||||
функциональный-тип-выражения-преобразования | (7) | ||||||||
где выражение-вызова-функции это
постфиксное-выражение ( список-выражений(необязательно) )
|
|||||||||
а функциональный-тип-выражения-преобразования следующие виды выражений, которые выполняют явное приведение:
спецификатор-простого-типа ( список-выражений(необязательно) )
|
(1) | ||||||||
спецификатор-typename ( список-выражений(необязательно) )
|
(2) | ||||||||
спецификатор-простого-типа список-инициализации-в-фигурных-скобках | (3) | ||||||||
спецификатор-typename список-инициализации-в-фигурных-скобках | (4) | ||||||||
Операндом для спецификатора-reflexpr должен быть тип, пространство имён, перечислитель, переменная, элемент-данных, параметр функции, захваченная сущность, выражение-вызова-функции или функциональный-тип-выражения-преобразования, и выражение в скобках. reflexpr(::) отражает глобальное пространство имён.
Для reflexpr-операнда формы (
выражение )
, выражение должно быть (возможно, в нескольких скобках) выражением-вызова-функции или функциональным-типом-выражения-преобразования.
Если операнд без скобок может рассматриваться либо как идентификатор-типа, либо как функциональный-тип-выражения-преобразования, то он рассматривается как идентификатор-типа. Круглые скобки могут использоваться для устранения неоднозначности между приведением в стиле функции и идентификатором-типа. Например, для типа класса X
с конструктором по умолчанию, reflexpr(X()) отражает тип функции X(), а reflexpr((X())) отражает выражение X().
Если операнд обозначает и псевдоним и имя класса, тип, представленный спецификатором-reflexpr, отражает псевдоним и соответствует reflect::Alias
.
Если операнд обозначает имя, объявление которого заключено в область видимости блока, а именованная сущность не захвачена и не является параметром функции, программа имеет неправильный формат.
[править] Типы метаобъектов
Тип метаобъекта это безымянный, неполный тип класса области видимости пространства имён. Тип соответствует концепту reflect::Object
тогда и только тогда, когда он является метаобъектным типом. Типы метаобъектов могут соответствовать другим концептам, в зависимости от операнда для reflexpr
.
Неопределено, приводит ли многократное применение reflexpr
к одному и тому же операнду к тому же или к другому типу. Если тип метаобъекта отражает неполный тип класса, определённые преобразования типа не могут быть применены.
Тип метаобъекта позволяет проверять некоторые свойства операнда для reflexpr
с помощью свойств типа или преобразований типа с ним.
[править] Разрешение перегрузки
Если постфиксное-выражение выражения-вызова-функции имеет тип класса, то есть e в выражении-вызова-функции e(args) имеет тип класса, тогда определяемая пользователем функция преобразования типа постфиксного-выражения (e) не должна использоваться.
Если постфиксное-выражение не относится к типу класса, оно должно именовать функцию, которая является уникальным результатом разрешения перегрузки.
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)); // ошибка: используется функция // преобразования
[править] Связь с рефлексией
Псевдоним это имя, введённое объявлением typedef, объявлением псевдонима или using-объявлением.
Сущность или псевдоним B
связаны с рефлексией для сущности или псевдонима A
, если
-
A
иB
это одна и та же сущность или псевдоним, -
A
это переменная или перечислитель, аB
это типA
, -
A
это перечисление, аB
базовый типA
, -
A
это класс, аB
элемент или базовый классA
, -
A
это псевдоним не шаблона, который обозначает сущностьB
, -
A
не является глобальным пространством имён, аB
включающий класс или пространство имёнA
, -
A
выражение в скобках (B
), -
A
лямбда-захват типа замыканияB
, -
A
тип замыкания лямбда-захватаB
, -
B
это тип, указанный в функциональном-типе-выражения-преобразованияA
, -
B
это функция, выбранная разрешением перегрузки для выражения-вызова-функцииA
, -
B
тип возвращаемого значения, тип параметра или тип функции для функцииA
, или -
B
связано рефлексией с сущностью или псевдонимомX
, аX
связано рефлексией сA
.
Отношение связи с рефлексией рефлексивно и транзитивно, но не симметрично.
Неформально говоря, случай, когда B
связано рефлексией с A
, означает, что B
участвует в объявлении или определении A
.
Ноль или более последовательных применений преобразований типов, которые передают типы метаобъектов в тип, обозначенный как спецификатор-reflexpr, позволяют проверять сущности и псевдонимы, которые связаны с рефлексией операнда; такой тип метаобъекта, как говорят, отражает соответствующие связанные с рефлексией сущность или псевдоним.
struct X; struct B { using X = ::X; typedef X Y; }; struct D : B { using B::Y; }; // ::X, но не B::X или B::Y, связан с рефлексией D::Y
[править] Разное
- Выражение, используемое как reflexpr-операнд это неоценённое выражение и потенциально вычисленная константа.
- В целях определения переменных, захваченных в лямбда-выражении по умолчанию для захвата, операнд
reflexpr
не считается неоценённым операндом. - Функция или переменная со статической продолжительностью хранения отражённая типом метаобъекта
T
является использующей odr специализацией std::experimental::reflect::get_pointer<T>, как если бы она взяла адрес выражения-идентификатора, определяющего функцию или переменную. - Может быть несколько определений типа метаобъекта, если все операции с этим типом дают одинаковые результаты константного выражения.
- Тип является зависимым, если он обозначен спецификатором reflexpr, и операндом
- являющимся зависящим от типа выражением или (возможно, заключённым в скобки) функциональным-типом-выражения-преобразования с по крайней мере одним зависящим от типа непосредственным подвыражением, или
- обозначает зависимый тип или элемент неизвестной специализации или константное выражение, зависящее от значения.
[править] Ключевые слова
[править] Предопределённые макросы тестирования функциональности
__cpp_reflection (ТС рефлексии) |
значение не менее 201902 указывает, что ТС Рефлексии поддерживается (макроконстанта) |
[править] Поддержка библиотеки
[править] Концепты
Определены в заголовочном файле
<experimental/reflect> | |
Определены в пространстве имён
std::experimental::reflect | |
Определены в пространстве имён
std::experimental::reflect::v1 | |
(ТС рефлексии) |
указывает, что тип является типом метаобъекта (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта является типом метаобъекта последовательности (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает область видимости параметра шаблона (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает сущность или псевдоним со связанным (возможно, пустым) именем (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает псевдоним типа, псевдоним пространства имён или псевдоним, введённый using-объявлением (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает объявление-элемента класса (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает перечислитель (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает переменную или элемент данных (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта соответствует RecordMember , Enumerator или Variable , или отражает пространство имён, отличное от глобального пространства имён (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает сущность с типом (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает пространство имён (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает глобальное пространство имён (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает тип класса не объединения (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает тип перечисления (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает тип класса (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает пространство имён, класс, перечисление, функцию, тип замыкания, область видимости параметра шаблона (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает тип (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает перечислитель или переменную constexpr (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает непосредственный базовый класс, полученный из get_base_classes (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает параметр функции (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает функцию (включая конструкторы и деструкторы) (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает выражение (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает выражение в скобках (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает выражение-вызова-функции (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает выражение-преобразования-функционального-типа (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает функцию (исключая конструкторы и деструкторы) (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает функцию-элемент (исключая конструкторы и деструкторы) (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает специальную функцию-элемент (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает конструктор (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает деструктор (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает функцию оператор или функцию преобразования (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает функцию преобразования (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает тип замыкания неуниверсальной лямбды (концепт) |
(ТС рефлексии) |
указывает, что тип метаобъекта отражает лямбда-захват (концепт) |
[править] Мета-объектные операции
Определены в заголовочном файле
<experimental/reflect> | |
Определены в пространстве имён
std::experimental::reflect | |
Определены в пространстве имён
std::experimental::reflect::v1 | |
Операции с
| |
(ТС рефлексии) |
проверяет, отражают ли два типа метаобъектов одну и ту же сущность или псевдоним (шаблон класса) |
(ТС рефлексии) |
получает предполагаемый номер строки объявления отражённой сущности или псевдонима (шаблон класса) |
(ТС рефлексии) |
получает определяемый реализацией номер столбца объявления отражённой сущности или псевдонима (шаблон класса) |
(ТС рефлексии) |
получает предполагаемое имя файла объявления отражённой сущности или псевдонима (шаблон класса) |
Операции
| |
(ТС рефлексии) |
получает размер последовательности метаобъектов (шаблон класса) |
(ТС рефлексии) |
получает тип метаобъекта с указанным индексом в последовательности (шаблон класса) |
(ТС рефлексии) |
применяет шаблон к последовательности метаобъектов (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
проверяет, является ли отражённая сущность или псевдоним безымянным (шаблон класса) |
(ТС рефлексии) |
получает неквалифицированное имя отражённой сущности или псевдонима (шаблон класса) |
(ТС рефлексии) |
получает определяемое реализацией отображаемое имя отражённой сущности или псевдонима (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
получает тип метаобъекта, отражающий связанную сущность отражённого псевдонима (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
получает тип метаобъекта, отражающий тип отражённой сущности или псевдонима (шаблон класса) |
(ТС рефлексии) |
получает тип отражённого объекта или псевдонима (шаблон класса) |
(ТС рефлексии) |
проверяет, отражает ли тип метаобъекта тип перечисления (шаблон класса) |
(ТС рефлексии) |
проверяет, отражает ли тип метаобъекта тип объединения (шаблон класса) |
(ТС рефлексии) |
проверяет, отражает ли тип метаобъекта тип класса не объединения, в объявлении которого используется class или struct соответственно (шаблон класса) |
Операции
| |
(ТС рефлексии) |
получает тип метаобъекта, отражающий область видимости отражённой сущности или псевдонима (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
получает тип метаобъекта, отражающий базовый класс в данном отношении базового класса (шаблон класса) |
Операции
| |
(ТС рефлексии) |
проверяет, является ли отражённый элемент или базовый класс public (шаблон класса) |
(ТС рефлексии) |
проверяет, является ли отражённый элемент или базовый класс protected (шаблон класса) |
(ТС рефлексии) |
проверяет, является ли отражённый элемент или базовый класс private (шаблон класса) |
Операции с
| |
получает тип последовательности метаобъектов, элементы которого отражают public, доступные или все элементы данных отражённого класса (шаблон класса) | |
получает тип последовательности метаобъектов, элементы которого отражают public, доступные или все функции-элементы отражённого класса (шаблон класса) | |
(ТС рефлексии) |
получает тип последовательности метаобъектов, элементы которого отражают все конструкторы отражённого класса (шаблон класса) |
(ТС рефлексии) |
получает тип последовательности метаобъектов, элементы которого отражают все функции operator и функции преобразования, объявленные в отражённом классе (шаблон класса) |
(ТС рефлексии) |
получает тип метаобъекта, отражающий деструктор отражённого класса (шаблон класса) |
получает тип последовательности метаобъектов, элементы которого отражают public, доступные или все вложенные типы или определения типов элементов отражённого класса (шаблон класса) | |
получает тип последовательности метаобъектов, элементы которого отражают public, доступные или все базовые классы отражённого класса (шаблон класса) | |
Операции с
| |
(ТС рефлексии) |
проверяет, имеет ли отражённое перечисление область видимости (шаблон класса) |
(ТС рефлексии) |
получает тип последовательности метаобъектов, элементы которого отражают перечислители отражённого перечисления (шаблон класса) |
(ТС рефлексии) |
получает тип метаобъекта, отражающий базовый тип отражённого перечисления (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
получает значение отражённой переменной, которое является константным выражением (шаблон класса) |
(ТС рефлексии) |
проверяет, объявлена ли переменная как thread_local (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
проверяет, имеет ли отражённый параметр аргумент по умолчанию (шаблон класса) |
Операции
| |
(ТС рефлексии) |
получает тип последовательности метаобъектов, элементы которого отражают параметры отражённой функции (шаблон класса) |
(ТС рефлексии) |
проверяет, содержит ли список параметров отражённой функции параметр с многоточием (шаблон класса) |
(ТС рефлексии) |
проверяет, не выбрасывает ли исключение отражённая функция (шаблон класса) |
(ТС рефлексии) |
проверяет, удалена ли отражённая функция (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
проверяет, является ли отражённая переменная или функция constexpr (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
проверяет, является ли отражённое пространство имён или функция встроенными (шаблон класса) |
Операции
| |
(ТС рефлексии) |
получает тип метаобъекта, отражающий выражение без скобок отражённого выражения со скобками (шаблон класса) |
Операции
| |
(ТС рефлексии) |
получает тип метаобъекта, отражающий функцию в отражённом выражении-вызова-функции (шаблон класса) |
Операции
| |
(ТС рефлексии) |
получает тип метаобъекта, отражающий конструктор в отражённом выражении-преобразования-функционального-типа (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
получает адрес отражённой переменной или функции или значение указателя на элемент для отражённого нестатического элемента (шаблон класса) |
Операции
| |
проверяет, объявлена ли отражённая функция-элемент с квалификатором const, volatile, & или && соответственно (шаблон класса) | |
(ТС рефлексии) |
проверяет, переопределяет ли отражённая функция-элемент функцию-элемент базового класса (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
проверяет, помечены ли отраженные класс или функция-элемент как final (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
проверяет, имеет ли отражённая переменная статическую длительность хранения или отражённая функция-элемент статическая (шаблон класса) |
Операции
| |
(ТС рефлексии) |
проверяет, неявно ли объявлена отражённая специальная функция-элемент (шаблон класса) |
(ТС рефлексии) |
проверяет, задана ли отражённая специальная функция-элемент по умолчанию в её первом объявлении (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
проверяет, объявлены ли отражённый конструктор или функция преобразования как explicit (шаблон класса) |
Операции
| |
(ТС рефлексии) |
проверяет, является ли отражённая функция-элемент виртуальной (шаблон класса) |
(ТС рефлексии) |
проверяет, является ли отражённая функция-элемент чисто виртуальной (шаблон класса) |
Операции с
| |
(ТС рефлексии) |
получает тип последовательности метаобъектов, элементы которого отражают захваты отражённого типа замыкания (шаблон класса) |
(ТС рефлексии) |
проверяет, является ли значение по умолчанию для лямбда-выражения отражённого типа замыкания = или & соответственно (шаблон класса) |
(ТС рефлексии) |
проверяет, объявлен ли operator() отражённого типа замыкания как const (шаблон класса) |
Операции
| |
(ТС рефлексии) |
проверяет, явно ли захвачен отражённый лямбда-захват (шаблон класса) |
(ТС рефлексии) |
проверяет, является ли отражённый лямбда-захват захватом инициализации (шаблон класса) |
[править] Макросы тестирования функциональности библиотеки
Определены в заголовочном файле
<experimental/reflect> | |
__cpp_lib_reflection (ТС рефлексии) |
значение не менее 201902 указывает, что поддерживается библиотека поддержки ТС Рефлексии (макроконстанта) |
[править] Соответствие концептам
В следующей таблице указано, соответствует ли тип метаобъекта отражённого операнда концептам, введённым в ТС Рефлексии.
Категория | Операнды reflexpr
|
Соответствие концептам |
---|---|---|
Тип | имя-класса обозначает объединение | reflect::Union
|
имя-класса обозначает тип замыкания | reflect::Lambda
| |
имя-класса обозначает класс не объединение | reflect::Record
| |
имя-перечисления | reflect::Enum
| |
параметр-типа шаблона | reflect::Type , reflect::Alias
| |
спецификатор-decltype | reflect::Type , reflect::Alias
| |
имя-типа введённое using-объявлением | reflect::Type , reflect::Alias , reflect::ScopedMember
| |
любое другое typedef-имя | reflect::Type , reflect::Alias
| |
любой другой идентификатор-типа | reflect::Type
| |
Пространство имён | псевдоним-пространства-имён | reflect::Namespace , reflect::Alias
|
глобальное пространство имён | reflect::GlobalScope
| |
любое другое пространство-имён | reflect::Namespace
| |
Выражение | имя элемента данных | reflect::Variable
|
имя переменной | reflect::Variable
| |
имя перечислителя | reflect::Enumerator
| |
имя параметра функции | reflect::FunctionParameter
| |
имя захваченной сущности | reflect::LambdaCapture
| |
выражение в скобках | reflect::ParenthesizedExpression
| |
выражение-вызова-функции | reflect::FunctionCallExpression
| |
выражение-преобразования-функционального-типа | reflect::FunctionalTypeConversion
|
Если операнд в форме выражения-идентификатора является константным выражением, тип, указанный спецификатором reflexpr, также соответствует reflect::Constant
.
Если reflexpr-операнд обозначает элемент класса, тип, представленный спецификатором reflexpr, также соответствует reflect::RecordMember
.
[править] Смотрите также
содержит некоторую информацию о типе, сгенерированную реализацией. Это класс, возвращаемый оператором typeid. (класс) | |
(C++11) |
Информация о типе времени компиляции |
Метапрограммирование времени компиляции в C++ |