Declarations
Declaraciones son cómo los nombres se introducen (o reintroducen) en el programa C++. No todas las declaraciones realmente declaran algo, y cada tipo de entidad se declara de manera diferente. Definiciones son declaraciones que son suficientes para usar la entidad identificada por el nombre.
Una declaración es una de las siguientes:
- Definición de función
- Declaración de plantilla (incluyendo Especialización parcial de plantilla )
- Instanciación explícita de plantilla
- Especialización explícita de plantilla
- Definición de espacio de nombres
- Especificación de vinculación
|
(desde C++11) |
-
Declaración vacía (
;) - Una declaración de función sin una decl-specifier-seq :
attr
(opcional)
declarator
;
|
|||||||||
| attr | - | (since C++11) secuencia de cualquier número de atributos |
| declarator | - | un declarador de función |
- Esta declaración debe declarar un constructor, destructor o función de conversión de tipo definida por el usuario conversion function . Solo puede utilizarse como parte de una template declaration , explicit specialization , o explicit instantiation.
- block-declaration (una declaración que puede aparecer dentro de un bloque ), que, a su vez, puede ser una de las siguientes:
| (desde C++11) |
| (desde C++20) | |
|
(desde C++11) |
-
- declaración simple
Contenido
Declaración simpleUna declaración simple es una sentencia que introduce, crea e inicializa opcionalmente uno o varios identificadores, típicamente variables.
1) Un declarador con un inicializador.
2) Un declarador sin inicializador.
EspecificadoresEspecificadores de declaración ( decl-specifier-seq ) es una secuencia de los siguientes especificadores separados por espacios, en cualquier orden:
Atributos pueden aparecer en decl-specifier-seq , en cuyo caso se aplican al tipo determinado por los especificadores precedentes. Las repeticiones de cualquier especificador en una decl-specifier-seq , como const static const , o virtual inline virtual son errores , excepto que long puede aparecer dos veces (desde C++11) . DeclaradoresCada init-declarator en una init-declarator-list S D1, D2, D3 ; se procesa como si fuera una declaración independiente con los mismos especificadores: S D1 ; S D2 ; S D3 ; . Cada declarador introduce exactamente un objeto, referencia, función o (para declaraciones typedef) alias de tipo, cuyo tipo es proporcionado por decl-specifier-seq y opcionalmente modificado por operadores como & (referencia a) o [ ] (arreglo de) o ( ) (función que retorna) en el declarador. Estos operadores pueden aplicarse recursivamente, como se muestra a continuación. Un declarador es uno de los siguientes:
1)
El
name
que se declara.
2)
Un declarador que utiliza un
identificador calificado
(
qualified-id
) define o redeclara un
miembro de namespace
o
miembro de clase
previamente declarado.
4)
Declarador de puntero
: la declaración
S
*
D
;
declara
D
como un puntero al tipo determinado por
decl-specifier-seq
S
.
5)
Declaración de puntero a miembro
: la declaración
S C
::
*
D
;
declara
D
como un puntero a miembro de
C
de tipo determinado por
decl-specifier-seq
S
.
nested-name-specifier
es una
secuencia de nombres y operadores de resolución de ámbito
::
6)
Declarador de referencia Lvalue
: la declaración
S
&
D
;
declara
D
como una referencia Lvalue al tipo determinado por
decl-specifier-seq
S
.
7)
Declarador de referencia a valor derecho
: la declaración
S
&&
D
;
declara
D
como una referencia a valor derecho al tipo determinado por
decl-specifier-seq
S
.
8)
Declarador de arreglo
.
noptr-declarator
cualquier declarador válido, pero si comienza con *, &, o &&, debe estar rodeado por paréntesis.
9)
Declarador de función
.
noptr-declarator
cualquier declarador válido, pero si comienza con *, &, o &&, debe estar rodeado por paréntesis.
Puede terminar con el tipo de retorno final opcional.
(desde C++11)
10)
Declarador entre paréntesis.
cv es una secuencia de calificadores const y volatile , donde cada calificador puede aparecer como máximo una vez en la secuencia.
NotasCuando una block-declaration aparece dentro de un bloque , y un identificador introducido por una declaración fue previamente declarado en un bloque externo, la declaración externa queda oculta durante el resto del bloque. Si una declaración introduce una variable con duración de almacenamiento automático, se inicializa cuando se ejecuta su sentencia de declaración. Todas las variables automáticas declaradas en un bloque se destruyen al salir del bloque (independientemente de cómo se abandone el bloque: mediante exception , goto , o al alcanzar su final), en orden inverso a su orden de inicialización. EjemploNota: este ejemplo demuestra cómo se analizan algunas declaraciones complejas en términos de la gramática del lenguaje. Otras reglas mnemotécnicas populares son: la regla espiral , lectura de adentro hacia afuera , y la declaración refleja el uso . También existe un analizador automatizado en https://cdecl.org .
Ejecutar este código
#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)>); } Informes de defectosLos siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
Véase también
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||