Extensions for reflection
Les Extensions C++ pour la Réflexion, ISO/IEC TS 23619:2021, spécifient des modifications au langage de base et définissent de nouveaux composants pour la bibliothèque standard C++ listés sur cette page.
Le Reflection TS est basé sur la norme C++20 (sauf que la définition des concepts est spécifiée dans le style du Concepts TS ).
Modifications du langage de base
spécificateur reflexpr
Un
reflexpr-specifier
est de la forme
reflexpr
(
reflexpr-operand
)
, et spécifie un type méta-objet (voir ci-dessous).
reflexpr-operand peut être l'un des suivants :
::
|
(1) | ||||||||
| type-id | (2) | ||||||||
| nested-name-specifier (optionnel) namespace-name | (3) | ||||||||
| id-expression | (4) | ||||||||
(
expression
)
|
(5) | ||||||||
| function-call-expression | (6) | ||||||||
| functional-type-conv-expression | (7) | ||||||||
où function-call-expression est
postfix-expression
(
expression-list
(optionnel)
)
|
|||||||||
et functional-type-conv-expression sont les types d'expressions suivants qui effectuent une conversion explicite :
spécificateur-de-type-simple
(
liste-d'expressions
(optionnel)
)
|
(1) | ||||||||
spécificateur-de-typename
(
liste-d'expressions
(optionnel)
)
|
(2) | ||||||||
| spécificateur-de-type-simple liste-d'initialisation-entre-accolades | (3) | ||||||||
| spécificateur-de-typename liste-d'initialisation-entre-accolades | (4) | ||||||||
L'opérande du reflexpr-specifier doit être un type , namespace , énumérateur , variable, membre de données , paramètre de fonction , entité capturée , function-call-expression ou functional-type-conv-expression , et expression entre parenthèses. reflexpr ( :: ) reflète l'espace de noms global.
Pour un
opérande reflexpr
de la forme
(
expression
)
, l'
expression
doit être une
expression d'appel de fonction
(éventuellement entre plusieurs parenthèses) ou une
expression de conversion de type fonctionnel
.
Si un opérande non parenthésé peut être traité soit comme un
type-id
soit comme une
functional-type-conv-expression
, alors il est traité comme un
type-id
. Les parenthèses peuvent être utilisées pour lever l'ambiguïté entre un cast de style fonctionnel et un
type-id
. Par exemple, étant donné un type de classe
X
avec un constructeur par défaut,
reflexpr
(
X
(
)
)
reflète le type de fonction
X
(
)
, et
reflexpr
(
(
X
(
)
)
)
reflète l'expression
X
(
)
.
Si l'opérande désigne à la fois un alias et un nom de classe, le type représenté par le spécificateur reflexpr reflète l'alias et satisfait
reflect::Alias
.
Si l'opérande désigne un nom dont la déclaration est englobée dans une portée de bloc et que l'entité nommée n'est ni capturée ni un paramètre de fonction, le programme est mal formé.
Types de méta-objets
Un
type méta-objet
est un type de classe non nommé, incomplet et de portée d'espace de noms. Un type satisfait le concept
reflect::Object
si et seulement s'il s'agit d'un type méta-objet. Les types méta-objets peuvent satisfaire d'autres concepts, selon l'opérande de
reflexpr
.
Il n'est pas spécifié si l'application répétée de
reflexpr
au même opérande produit le même type ou un type différent. Si un type méta-objet reflète un type de classe incomplet, certaines transformations de types ne peuvent pas être appliquées.
Un type méta-objet permet l'inspection de certaines propriétés de l'opérande de
reflexpr
à travers des traits de type ou des transformations de type sur celui-ci.
Résolution de surcharge
Si le postfix-expression de la function-call-expression est de type classe, c'est-à-dire e dans la function-call-expression e ( args ) est de type classe, alors la fonction de conversion définie par l'utilisateur du type du postfix-expression ( e ) ne doit pas être utilisée.
Si postfix-expression n'est pas de type classe, il doit désigner une fonction qui est le résultat unique de la résolution de surcharge.
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)); // erreur: fonction de conversion utilisée
Un alias est un nom introduit par une typedef , une alias-declaration , ou une using-declaration .
Une entité ou alias
B
est
lié par réflexion
à une entité ou alias
A
si
-
AetBsont la même entité ou un alias, -
Aest une variable ou un énumérateur etBest le type deA, -
Aest une énumération etBest le type sous-jacent deA, -
Aest une classe etBest un membre ou une classe de base deA, -
Aest un alias non-template qui désigne l'entitéB, -
An'est pas l'espace de noms global etBest une classe ou un espace de noms englobant deA, -
Aest l'expression entre parenthèses (B), -
Aest une capture lambda du type de fermetureB, -
Aest le type de fermeture de la capture lambdaB, -
Best le type spécifié par l' expression-de-conversion-de-type-fonctionnelA, -
Best la fonction sélectionnée par la résolution de surcharge pour une expression-d'appel-de-fonctionA, -
Best le type de retour, un type de paramètre ou le type de fonction de la fonctionA, ou -
Best lié par réflexion à une entité ou un aliasXetXest lié par réflexion àA.
La relation de réflexion-relation est réflexive et transitive, mais pas symétrique.
De manière informelle, le cas où
B
est lié par réflexion à
A
signifie que
B
participe à la déclaration ou à la définition de
A
.
Zéro ou plusieurs applications successives de transformations de type qui produisent des types méta-objets au type dénoté par un reflexpr-specifier permettent l'inspection d'entités et d'alias qui sont liés par réflexion à l'opérande ; un tel type méta-objet est dit refléter l'entité ou l'alias lié par réflexion respectif.
struct X; struct B { using X = ::X; typedef X Y; }; struct D : B { using B::Y; }; // Seul ::X, mais pas B::X ou B::Y, est lié à la réflexion avec D::Y
Divers
- Une expression utilisée comme opérande-reflexpr est une expression non évaluée et potentiellement évaluée comme constante .
-
Pour la détermination des variables
capturées dans une expression lambda
par une capture par défaut, un opérande
reflexprn'est pas considéré comme un opérande non évalué. -
Une fonction ou variable de durée de stockage
statique
reflétée par le type méta-objet
Test odr-utilisée par la spécialisation std :: experimental :: reflect :: get_pointer < T > , comme si l'adresse d'une expression d'identifiant désignant la fonction ou variable était prise. - Il peut y avoir plus d'une définition d'un type méta-objet, tant que toutes les opérations sur ce type produisent les mêmes résultats d'expression constante.
-
Un type est
dépendant
s'il est désigné par un spécificateur reflexpr, et que l'opérande
- est une expression dépendante du type ou une expression de conversion de type fonctionnel (éventuellement parenthésée) avec au moins une sous-expression immédiate dépendante du type, ou
- désigne un type dépendant ou un membre d'une spécialisation inconnue ou une expression constante dépendante de la valeur .
Mots-clés
Macros prédéfinis de test de fonctionnalités
|
__cpp_reflection
(reflection TS)
|
une valeur d'au moins
201902
indique que le Reflection TS est pris en charge
(constante macro) |
Support de la bibliothèque
Concepts
|
Défini dans l'en-tête
<experimental/reflect>
|
|
|
Défini dans l'espace de noms
std::experimental::reflect
|
|
|
Défini dans l'espace de noms en ligne
std::experimental::reflect::v1
|
|
|
(reflection TS)
|
spécifie qu'un type est un type méta-objet
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet est un type de séquence méta-objet
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une portée de paramètre de modèle
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une entité ou un alias avec un nom associé (éventuellement vide)
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un alias de type, un alias d'espace de noms, ou un alias introduit par une déclaration using
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une
member-declaration
d'une classe
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un énumérateur
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une variable ou un membre de données
(concept) |
|
(reflection TS)
|
spécifie qu'un type de méta-objet satisfait
RecordMember
,
Enumerator
, ou
Variable
, ou reflète un espace de noms autre que l'espace de noms global
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une entité ayant un type
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un espace de noms
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète l'espace de noms global
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un type classe non-union
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un type énumération
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un type classe
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un espace de noms, une classe, une énumération, une fonction, un type de fermeture, ou une portée de paramètre de modèle
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un type
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un énumérateur ou une variable constexpr
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une classe de base directe obtenue à partir de
get_base_classes
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un paramètre de fonction
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une fonction (y compris les constructeurs et destructeurs)
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une expression
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une expression entre parenthèses
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une
expression d'appel de fonction
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une
functional-type-conv-expression
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une fonction (à l'exclusion des constructeurs et destructeurs)
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une fonction membre (à l'exclusion des constructeurs et destructeurs)
(concept) |
|
(reflection TS)
|
spécifie qu'un type de méta-objet reflète une fonction membre spéciale
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un constructeur
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète un destructeur
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une fonction opérateur ou une fonction de conversion
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une fonction de conversion
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète le type de fermeture d'un lambda non générique
(concept) |
|
(reflection TS)
|
spécifie qu'un type méta-objet reflète une capture lambda
(concept) |
Opérations méta-objet
|
Défini dans l'en-tête
<experimental/reflect>
|
|
|
Défini dans l'espace de noms
std::experimental::reflect
|
|
|
Défini dans l'espace de noms en ligne
std::experimental::reflect::v1
|
|
|
|
|
(reflection TS)
|
vérifie si deux types de méta-objets reflètent la même entité ou alias
(modèle de classe) |
|
(reflection TS)
|
obtient le numéro de ligne présumé de la déclaration de l'entité réfléchie ou de l'alias
(modèle de classe) |
|
(reflection TS)
|
obtient le numéro de colonne défini par l'implémentation de la déclaration de l'entité réfléchie ou de l'alias
(modèle de classe) |
|
(reflection TS)
|
obtient le nom de fichier présumé de la déclaration de l'entité réfléchie ou de l'alias
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient la taille d'une séquence de méta-objets
(modèle de classe) |
|
(reflection TS)
|
obtient le type méta-objet avec l'index spécifié dans une séquence
(modèle de classe) |
|
(reflection TS)
|
applique un modèle à la séquence de méta-objets
(modèle de classe) |
|
|
|
(reflection TS)
|
vérifie si l'entité réfléchie ou l'alias n'a pas de nom
(modèle de classe) |
|
(reflection TS)
|
obtient le nom non qualifié de l'entité réfléchie ou de l'alias
(modèle de classe) |
|
(reflection TS)
|
obtient le nom d'affichage défini par l'implémentation de l'entité réfléchie ou de l'alias
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient le type méta-objet reflétant l'entité associée de l'alias réfléchi
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient le type de méta-objet reflétant le type de l'entité ou alias réfléchi
(modèle de classe) |
|
(reflection TS)
|
obtient le type de l'entité réfléchie ou de l'alias
(modèle de classe) |
|
(reflection TS)
|
vérifie si le type méta-objet reflète un type énumération
(modèle de classe) |
|
(reflection TS)
|
vérifie si le type méta-objet reflète un type union
(modèle de classe) |
|
(reflection TS)
|
vérifie si le type de méta-objet reflète un type de classe non-union dont la déclaration utilise
class
ou
struct
respectivement
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient le type de méta-objet reflétant la portée de l'entité ou alias réfléchi
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient le type de méta-objet reflétant la classe de base dans la relation de classe de base donnée
(modèle de classe) |
|
|
|
(reflection TS)
|
vérifie si le membre réfléchi ou la classe de base est public
(modèle de classe) |
|
(reflection TS)
|
vérifie si le membre réfléchi ou la classe de base est protégé
(modèle de classe) |
|
(reflection TS)
|
vérifie si le membre réfléchi ou la classe de base est privé
(modèle de classe) |
|
|
|
obtient un type de séquence de méta-objets dont les éléments reflètent les membres de données publics, accessibles ou tous les membres de données de la classe reflétée
(modèle de classe) |
|
|
obtient un type de séquence de méta-objets dont les éléments reflètent les fonctions membres publiques, accessibles ou toutes les fonctions membres de la classe réfléchie
(modèle de classe) |
|
|
(reflection TS)
|
obtient un type de séquence de méta-objets dont les éléments reflètent tous les constructeurs de la classe réfléchie
(modèle de classe) |
|
(reflection TS)
|
obtient un type de séquence de méta-objets dont les éléments reflètent toutes les fonctions opérateur et fonctions de conversion déclarées dans la classe réfléchie
(modèle de classe) |
|
(reflection TS)
|
obtient le type de méta-objet reflétant le destructeur de la classe réfléchie
(modèle de classe) |
|
obtient un type de séquence de méta-objets dont les éléments reflètent les types imbriqués publics, accessibles ou tous les typedefs membres de la classe réfléchie
(modèle de classe) |
|
|
obtient un type de séquence de méta-objets dont les éléments reflètent les classes de base publiques, accessibles ou toutes les classes de base de la classe reflétée
(modèle de classe) |
|
|
|
|
(reflection TS)
|
vérifie si l'énumération réfléchie est délimitée
(modèle de classe) |
|
(reflection TS)
|
obtient un type de séquence de méta-objets dont les éléments reflètent les énumérateurs de l'énumération réfléchie
(modèle de classe) |
|
(reflection TS)
|
obtient le type méta-objet reflétant le type sous-jacent de l'énumération réfléchie
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient la valeur de la variable réfléchie qui est une expression constante
(modèle de classe) |
|
(reflection TS)
|
vérifie si la variable est déclarée avec
thread_local
(modèle de classe) |
|
|
|
(reflection TS)
|
vérifie si le paramètre réfléchi possède un argument par défaut
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient un type de séquence de méta-objets dont les éléments reflètent les paramètres de la fonction réfléchie
(modèle de classe) |
|
(reflection TS)
|
vérifie si la liste de paramètres de la fonction réfléchie contient un paramètre ellipsis
(modèle de classe) |
|
(reflection TS)
|
vérifie si la fonction réfléchie est non-lançante
(modèle de classe) |
|
(reflection TS)
|
vérifie si la fonction réfléchie est supprimée
(modèle de classe) |
|
|
|
(reflection TS)
|
vérifie si la variable ou fonction réfléchie est constexpr
(modèle de classe) |
|
|
|
(reflection TS)
|
vérifie si l'espace de noms ou la fonction réfléchi(e) est inline
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient le type méta-objet reflétant l'expression sans parenthèses de l'expression parenthésée réfléchie
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient le type de méta-objet reflétant la fonction dans l'expression
function-call-expression
réfléchie
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient le type de méta-objet reflétant le constructeur dans l'expression
functional-type-conv-expression
reflétée
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient l'adresse de la variable ou fonction réfléchie, ou la valeur pointeur-vers-membre vers le membre non statique réfléchi
(modèle de classe) |
|
|
|
vérifie si la fonction membre réfléchie est déclarée avec
const
,
volatile
,
&
, ou
&&
qualificateur respectivement
(modèle de classe) |
|
|
(reflection TS)
|
vérifie si la fonction membre réfléchie redéfinit une fonction membre de la classe de base
(modèle de classe) |
|
|
|
(reflection TS)
|
vérifie si la classe réfléchie ou la fonction membre est marquée avec
final
(modèle de classe) |
|
|
|
(reflection TS)
|
vérifie si la variable réfléchie a une durée de stockage statique, ou si la fonction membre réfléchie est statique
(modèle de classe) |
|
|
|
(reflection TS)
|
vérifie si la fonction membre spéciale réfléchie est implicitement déclarée
(modèle de classe) |
|
(reflection TS)
|
vérifie si la fonction membre spéciale réfléchie est définie par défaut dans sa première déclaration
(modèle de classe) |
|
|
|
(reflection TS)
|
vérifie si le constructeur ou la fonction de conversion réfléchi est déclaré avec
explicit
(modèle de classe) |
|
|
|
(reflection TS)
|
vérifie si la fonction membre réfléchie est virtuelle
(modèle de classe) |
|
(reflection TS)
|
vérifie si la fonction membre réfléchie est virtuelle pure
(modèle de classe) |
|
|
|
(reflection TS)
|
obtient un type de séquence de méta-objets dont les éléments reflètent les captures du type de fermeture réfléchi
(modèle de classe) |
|
(reflection TS)
|
vérifie si la capture par défaut de l'expression lambda du type de fermeture reflété est
=
ou
&
respectivement
(modèle de classe) |
|
(reflection TS)
|
vérifie si l'
operator()
du type de fermeture réfléchi est déclaré avec
const
(modèle de classe) |
|
|
|
(reflection TS)
|
vérifie si la capture de lambda réfléchie est explicitement capturée
(modèle de classe) |
|
(reflection TS)
|
vérifie si la capture de lambda réfléchie est une capture d'initialisation
(modèle de classe) |
Macros de test de fonctionnalités de la bibliothèque
|
Défini dans l'en-tête
<experimental/reflect>
|
|
|
__cpp_lib_reflection
(reflection TS)
|
une valeur d'au moins
201902
indique que la bibliothèque de support du Reflection TS est prise en charge
(constante macro) |
Satisfaction des concepts
Le tableau suivant indique si un type méta-objet reflétant un opérande satisfait aux concepts introduits par le Reflection TS.
| Catégorie |
reflexpr
opérandes
|
Concepts satisfaits |
|---|---|---|
| Type | class-name désignant une union |
reflect::Union
|
| class-name désignant un type de fermeture |
reflect::Lambda
|
|
| class-name désignant une classe non-union |
reflect::Record
|
|
| enum-name |
reflect::Enum
|
|
| template type-parameter |
reflect::Type
,
reflect::Alias
|
|
| decltype-specifier |
reflect::Type
,
reflect::Alias
|
|
| type-name introduit par une using-declaration |
reflect::Type
,
reflect::Alias
,
reflect::ScopedMember
|
|
| tout autre typedef-name |
reflect::Type
,
reflect::Alias
|
|
| tout autre type-id |
reflect::Type
|
|
| Namespace | namespace-alias |
reflect::Namespace
,
reflect::Alias
|
| l'espace de noms global |
reflect::GlobalScope
|
|
| tout autre namespace |
reflect::Namespace
|
|
| Expression | le nom d'un membre de données |
reflect::Variable
|
| le nom d'une variable |
reflect::Variable
|
|
| le nom d'un énumérateur |
reflect::Enumerator
|
|
| le nom d'un paramètre de fonction |
reflect::FunctionParameter
|
|
| le nom d'une entité capturée |
reflect::LambdaCapture
|
|
| expression entre parenthèses |
reflect::ParenthesizedExpression
|
|
| function-call-expression |
reflect::FunctionCallExpression
|
|
| functional-type-conv-expression |
reflect::FunctionalTypeConversion
|
Si l'opérande de la forme expression d'identifiant est une expression constante, le type spécifié par le spécificateur reflexpr satisfait également
reflect::Constant
.
Si l'opérande de reflexpr désigne un membre de classe, le type représenté par le spécificateur reflexpr satisfait également
reflect::RecordMember
.
Voir aussi
|
contient les informations d'un type, la classe renvoyée par l'opérateur typeid
(classe) |
|
|
(C++11)
|
Utilitaires d'information de type à la compilation |