Declarations
Déclarations sont la manière dont les noms sont introduits (ou réintroduits) dans le programme C++. Toutes les déclarations ne déclarent pas réellement quelque chose, et chaque type d'entité est déclaré différemment. Définitions sont des déclarations qui sont suffisantes pour utiliser l'entité identifiée par le nom.
Une déclaration est l'une des suivantes :
- Définition de fonction
- Déclaration de template (incluant Spécialisation partielle de template )
- Instanciation explicite de template
- Spécialisation explicite de template
- Définition d'espace de noms
- Spécification de liaison
|
(depuis C++11) |
-
Déclaration vide (
;) - Une déclaration de fonction sans decl-specifier-seq :
attr
(facultatif)
déclarateur
;
|
|||||||||
| attr | - | (since C++11) séquence d'un nombre quelconque d' attributs |
| declarator | - | un déclarateur de fonction |
- Cette déclaration doit déclarer un constructeur, un destructeur, ou une fonction de conversion conversion function . Elle ne peut être utilisée que comme partie d'une template declaration , explicit specialization , ou explicit instantiation.
- block-declaration (une déclaration qui peut apparaître à l'intérieur d'un bloc ), qui, à son tour, peut être l'une des suivantes :
| (depuis C++11) |
| (depuis C++20) | |
|
(depuis C++11) |
-
- déclaration simple
Sommaire
Déclaration simpleUne déclaration simple est une instruction qui introduit, crée et initialise éventuellement un ou plusieurs identifiants, généralement des variables.
1) Un déclarateur avec un initialiseur.
2) Un déclarateur sans initialiseur.
SpécificateursSpécificateurs de déclaration ( decl-specifier-seq ) est une séquence des spécificateurs suivants, séparés par des espaces, dans n'importe quel ordre :
Attributs peuvent apparaître dans decl-specifier-seq , auquel cas ils s'appliquent au type déterminé par les spécificateurs précédents. Les répétitions de tout spécificateur dans une decl-specifier-seq , telles que const static const , ou virtual inline virtual sont des erreurs , sauf que long est autorisé à apparaître deux fois (depuis C++11) . DéclarateursChaque init-declarator dans une init-declarator-list S D1, D2, D3 ; est traité comme s'il s'agissait d'une déclaration autonome avec les mêmes spécificateurs : S D1 ; S D2 ; S D3 ; . Chaque déclarateur introduit exactement un objet, référence, fonction ou (pour les déclarations typedef) alias de type, dont le type est fourni par decl-specifier-seq et optionnellement modifié par des opérateurs tels que & (référence vers) ou [ ] (tableau de) ou ( ) (fonction retournant) dans le déclarateur. Ces opérateurs peuvent être appliqués récursivement, comme montré ci-dessous. Un déclarateur est l'un des éléments suivants :
1)
Le
nom
qui est déclaré.
2)
Un déclarateur qui utilise un
identifiant qualifié
(
qualified-id
) définit ou redéclare un
membre d'espace de noms
ou un
membre de classe
précédemment déclaré.
4)
Déclarateur de pointeur
: la déclaration
S
*
D
;
déclare
D
comme un pointeur vers le type déterminé par
decl-specifier-seq
S
.
5)
Déclaration de pointeur vers membre
: la déclaration
S C
::
*
D
;
déclare
D
comme un pointeur vers membre de
C
de type déterminé par
decl-specifier-seq
S
.
nested-name-specifier
est une
séquence de noms et d'opérateurs de résolution de portée
::
6)
Déclarateur de référence Lvalue
: la déclaration
S
&
D
;
déclare
D
comme une référence Lvalue vers le type déterminé par
decl-specifier-seq
S
.
7)
Déclarateur de référence à valeur résiduelle
: la déclaration
S
&&
D
;
déclare
D
comme une référence à valeur résiduelle vers le type déterminé par
decl-specifier-seq
S
.
8)
Déclarateur de tableau
.
noptr-declarator
tout déclarateur valide, mais s'il commence par *, &, ou &&, il doit être entouré de parenthèses.
9)
Déclarateur de fonction
.
noptr-declarator
tout déclarateur valide, mais s'il commence par *, &, ou &&, il doit être entouré de parenthèses.
Il peut se terminer par le type de retour optionnel en suffixe.
(depuis C++11)
10)
Déclarateur entre parenthèses.
cv est une séquence de qualificateurs const et volatile , où chaque qualificateur peut apparaître au plus une fois dans la séquence.
NotesLorsqu'une block-declaration apparaît à l'intérieur d'un bloc , et qu'un identifiant introduit par une déclaration a été précédemment déclaré dans un bloc externe, la déclaration externe est masquée pour le reste du bloc. Si une déclaration introduit une variable avec une durée de stockage automatique, elle est initialisée lorsque son instruction de déclaration est exécutée. Toutes les variables automatiques déclarées dans un bloc sont détruites à la sortie du bloc (peu importe comment le bloc est quitté : via exception , goto , ou en atteignant sa fin), dans l'ordre inverse de leur ordre d'initialisation. ExempleNote : cet exemple démontre comment certaines déclarations complexes sont analysées en termes de grammaire du langage. D'autres mnémoniques populaires sont : la règle en spirale , la lecture de l'intérieur vers l'extérieur , et la déclaration reflète l'utilisation . Il existe également un analyseur automatisé sur https://cdecl.org .
Exécuter ce code
#include <type_traits> struct S { int member; // decl-specifier-seq is "int" // declarator is "member" } obj, *pObj(&obj); // decl-specifier-seq is "struct S { int member; }" // declarator "obj" declares an object of type S // declarator "*pObj" declares a pointer to S, // and initializer "(&obj)" initializes it int i = 1, *p = nullptr, f(), (*pf)(double); // decl-specifier-seq is "int" // declarator "i" declares a variable of type int, // and initializer "= 1" initializes it // declarator "*p" declares a variable of type int*, // and initializer "= nullptr" initializes it // declarator "f()" declares (but doesn't define) // a function taking no arguments and returning int // declarator "(*pf)(double)" declares a pointer to function // taking double and returning int int (*(*var1)(double))[3] = nullptr; // decl-specifier-seq is "int" // declarator is "(*(*var1)(double))[3]" // initializer is "= nullptr" // 1. declarator "(*(*var1)(double))[3]" is an array declarator: // Type declared is: "(*(*var1)(double))" array of 3 elements // 2. declarator "(*(*var1)(double))" is a pointer declarator: // Type declared is: "(*var1)(double)" pointer to array of 3 elements // 3. declarator "(*var1)(double)" is a function declarator: // Type declared is: "(*var1)" function taking "(double)", // returning pointer to array of 3 elements. // 4. declarator "(*var1)" is a pointer declarator: // Type declared is: "var1" pointer to function taking "(double)", // returning pointer to array of 3 elements. // 5. declarator "var1" is an identifier. // This declaration declares the object var1 of type "pointer to function // taking double and returning pointer to array of 3 elements of type int" // The initializer "= nullptr" provides the initial value of this pointer. // C++11 alternative syntax: auto (*var2)(double) -> int (*)[3] = nullptr; // decl-specifier-seq is "auto" // declarator is "(*var2)(double) -> int (*)[3]" // initializer is "= nullptr" // 1. declarator "(*var2)(double) -> int (*)[3]" is a function declarator: // Type declared is: "(*var2)" function taking "(double)", returning "int (*)[3]" // ... int main() { static_assert(std::is_same_v<decltype(var1), decltype(var2)>); } Rapports de défautsLes rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
Voir aussi
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||