Identifiers
Un identifiant est une séquence arbitrairement longue de chiffres, de traits de soulignement, de lettres latines minuscules et majuscules, et de la plupart des caractères Unicode.
Le premier caractère d'un identifiant valide doit être l'un des suivants :
- lettres latines majuscules A-Z
- lettres latines minuscules a-z
- trait de soulignement
- tout caractère Unicode possédant la propriété Unicode XID_Start
Tout autre caractère d'un identifiant valide doit être l'un des suivants :
- chiffres 0-9
- lettres latines majuscules A-Z
- lettres latines minuscules a-z
- tiret bas
- tout caractère Unicode possédant la propriété Unicode XID_Continue
Les listes de caractères avec les propriétés XID_Start et XID_Continue peuvent être trouvées dans DerivedCoreProperties.txt .
Les identifiants sont sensibles à la casse (les minuscules et majuscules sont distinctes), et chaque caractère est significatif. Chaque identifiant doit être conforme à la Normalization Form C .
Remarque : La prise en charge des identifiants Unicode est limitée dans la plupart des implémentations, par exemple gcc (jusqu'à la version 10) .
Table des matières |
Dans les déclarations
Un identifiant peut être utilisé pour nommer des objets, des références, des fonctions, des énumérateurs, des types, des membres de classe, des espaces de noms, des templates, des spécialisations de templates, des packs de paramètres (depuis C++11) , des étiquettes goto, et d'autres entités, avec les exceptions suivantes :
- Les identifiants qui sont des mots-clés ne peuvent pas être utilisés à d'autres fins.
|
(depuis C++11) |
- Les identifiants qui sont des représentations alternatives pour certains opérateurs et signes de ponctuation ne peuvent pas être utilisés à d'autres fins.
|
(depuis C++11) |
-
Identifiants
qui apparaissent comme un jeton ou un jeton de prétraitement (c'est-à-dire pas dans
user-defined-string-literal
comme
operator
""
id
)
(depuis C++11)
ayant l'une des formes suivantes sont réservés :
- dans l'espace de noms global, les identifiants qui commencent par un trait de soulignement
- les identifiants qui contiennent un double trait de soulignement ou commencent par un trait de soulignement suivi d'une lettre majuscule, à l'exception des identifiants suivants :
-
-
- macros prédéfinis (incluant macros de test de fonctionnalités du langage ) (depuis C++20)
-
| (depuis C++11) |
|
(depuis C++11) |
| (depuis C++20) |
« Réservé » signifie ici que les en-têtes standards de la bibliothèque #define ou déclarent ces identifiants pour leurs besoins internes, le compilateur peut prédéfinir des identifiants non standards de ce type, et l'algorithme de mangling de noms peut supposer que certains de ces identifiants ne sont pas utilisés. Si le programmeur utilise de tels identifiants, le programme est mal formé, aucun diagnostic requis.
De plus, il est un comportement indéfini de #define ou #undef certains noms dans une unité de traduction, consultez les noms de macros réservés pour plus de détails.
Identifiants zombies
À partir de C++14, certains identifiants sont supprimés de la bibliothèque standard C++. Ils sont listés dans la liste des noms zombies .
Cependant, ces identifiants restent réservés pour la normalisation précédente dans un certain contexte. Les noms de fonctions membres supprimées ne peuvent pas être utilisés comme nom pour des macros de type fonction, et les autres noms de membres supprimés ne peuvent pas être utilisés comme nom pour des macros de type objet dans du code portable.
Dans les expressions
Un identifiant qui nomme une variable, une fonction, une spécialisation d'un concept , (depuis C++20) ou un énumérateur peut être utilisé comme expression . Le résultat d'une expression constituée uniquement de l'identifiant est l'entité nommée par l'identifiant. La catégorie de valeur de l'expression est lvalue si l'identifiant nomme une fonction, une variable , un objet paramètre de modèle (depuis C++20) , ou un membre de données, et rvalue (jusqu'à C++11) prvalue (depuis C++11) sinon (par exemple, un énumérateur est une expression rvalue (jusqu'à C++11) une expression prvalue (depuis C++11) , une spécialisation d'un concept est une prvalue booléenne (depuis C++20) ).
Type
Le type d'une expression d'identifiant est le même que le type de l'entité qu'il nomme.
|
Les exceptions suivantes existent :
void f() { float x, &r = x; [=] { decltype(x) y1; // y1 has type float decltype((x)) y2 = y1; // y2 has type float const& because this lambda // is not mutable and x is an lvalue decltype(r) r1 = y1; // r1 has type float& decltype((r)) r2 = y2; // r2 has type float const& }; }
|
(depuis C++11) |
Identifiants non qualifiés
En plus des identifiants dûment déclarés, les éléments suivants peuvent être utilisés dans les expressions dans le même rôle :
- un opérateur surchargé en notation fonctionnelle, tel que operator + ou operator new ;
- une fonction de conversion définie par l'utilisateur , telle que operator bool ;
|
(depuis C++11) |
- un nom de template suivi de sa liste d'arguments, tel que MyTemplate < int > ;
- le caractère ~ suivi d'un nom de classe, tel que ~MyClass ;
|
(depuis C++11) |
|
(depuis C++26) |
Ensemble avec les identifiants, ils sont connus sous le nom d' expressions d'identifiants non qualifiés .
Identifiants qualifiés
Un expression d'identifiant qualifié est un expression d'identifiant non qualifié précédé d'un opérateur de résolution de portée :: , et optionnellement, une séquence de l'un des éléments suivants séparés par des opérateurs de résolution de portée :
- un nom de namespace ;
- un nom de classe ;
|
(depuis C++11) |
|
(depuis C++26) |
Par exemple, l'expression std:: string :: npos est une expression qui désigne le membre statique npos dans la classe string de l'espace de noms std . L'expression :: tolower désigne la fonction tolower dans l'espace de noms global. L'expression :: std:: cout désigne la variable globale cout dans l'espace de noms std , qui est un espace de noms de premier niveau. L'expression boost :: signals2 :: connection désigne le type connection déclaré dans l'espace de noms signals2 , qui est déclaré dans l'espace de noms boost .
Le mot-clé template peut apparaître dans les identifiants qualifiés si nécessaire pour lever l'ambiguïté des noms de template dépendants .
Voir qualified lookup pour les détails de la recherche de nom pour les identifiants qualifiés.
Transformation d'accès implicite aux membres
Si une expression d'identificateur
E
désigne un membre non-type non-statique d'une classe
C
et que toutes les conditions suivantes sont satisfaites,
E
est transformée en expression d'accès au membre de classe
this
-
>
E
:
- E n'est pas l'opérande droit d'un opérateur d'accès membre .
- Si E est une expression d'identifiant qualifié, E n'est pas l'opérande non parenthésé d'un opérateur d'adresse .
- L'une des conditions suivantes est satisfaite :
-
- E est potentiellement évalué .
-
Cest la classe englobante la plus interne à E . -
Cest une classe de base de la classe englobante la plus interne à E .
Cette transformation ne s'applique pas dans le contexte de définition de template (voir dependent names ).
struct X { int x; }; struct B { int b; }; struct D : B { X d; void func() { d; // OK, sera transformé en this->d b; // OK, sera transformé en this->b x; // Erreur : this->x est incorrect d.x; // OK, sera transformé en this->d.x // au lieu de d.this->x ou this->d.this->x } };
Noms
Un nom est l'utilisation de l'un des éléments suivants pour faire référence à une entité :
- un identifiant
- un nom d'opérateur surchargé en notation fonction ( operator + , operator new )
- un nom de fonction de conversion définie par l'utilisateur ( operator bool )
|
(depuis C++11) |
- un nom de template suivi de sa liste d'arguments ( MyTemplate < int > )
Chaque nom est introduit dans le programme par une déclaration . Un nom utilisé dans plus d'une unité de traduction peut faire référence aux mêmes entités ou à des entités différentes, selon la liaison .
Lorsque le compilateur rencontre un nom inconnu dans un programme, il l'associe à la déclaration qui a introduit le nom au moyen d'une recherche de nom , à l'exception des noms dépendants dans les déclarations et définitions de templates (pour ces noms, le compilateur détermine s'ils désignent un type, un template ou une autre entité, ce qui peut nécessiter une désambiguïsation explicite ).
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| CWG 1440 | C++11 |
les expressions decltype précédant
::
pouvaient désigner n'importe quel type
|
ne peuvent désigner que des types classe
ou énumération |
| CWG 1963 | C++11 |
les caractères définis par l'implémentation autres que les chiffres, non-chiffres
et les noms de caractères universels pouvaient être utilisés dans un identifiant |
interdit |
| CWG 2521 | C++11 |
l'identifiant dans
user-defined-string-literal
d'un
opérateur littéral était réservé comme d'habitude |
les règles sont différentes |
| CWG 2771 | C++98 | & a n'était pas transformé en & this - > a dans les contextes de classe | il est transformé |
| CWG 2777 | C++20 |
le type d'une expression identifiant n'était pas clair
si elle nomme un objet paramètre de template |
clarifié |
| CWG 2818 | C++98 | les noms de macros prédéfinies sont réservés | ils ne sont pas réservés |
Voir aussi
|
Documentation C
pour
Identifiers
|