Declarations
Объявления — это способ введения (или повторного введения) имен в программу на C++. Не все объявления действительно что-либо объявляют, и каждый вид сущности объявляется по-разному. Определения — это объявления, которые достаточны для использования сущности, идентифицируемой именем.
Объявление представляет собой одно из следующих:
- Определение функции
- Объявление шаблона (включая Частичную специализацию шаблона )
- Явное инстанцирование шаблона
- Явная специализация шаблона
- Определение пространства имён
- Спецификация компоновки
|
(начиная с C++11) |
-
Пустое объявление (
;) - Объявление функции без decl-specifier-seq :
attr
(необязательно)
декларатор
;
|
|||||||||
| attr | - | (since C++11) последовательность любого количества attributes |
| declarator | - | функциональный декларатор |
- Данное объявление должно объявлять конструктор, деструктор или пользовательскую conversion function . Оно может использоваться только как часть template declaration , explicit specialization , или explicit instantiation.
- block-declaration (объявление, которое может находиться внутри блока ), которое, в свою очередь, может быть одним из следующих:
| (начиная с C++11) |
| (начиная с C++20) | |
| (начиная с C++11) |
-
- простая декларация
Содержание
Простое объявлениеПростое объявление — это оператор, который вводит, создаёт и, возможно, инициализирует один или несколько идентификаторов, обычно переменных.
1) declarator с инициализатором.
2) declarator без инициализатора.
СпецификаторыСпецификаторы объявления ( decl-specifier-seq ) представляет собой последовательность следующих разделенных пробелами спецификаторов в произвольном порядке:
Атрибуты могут появляться в decl-specifier-seq , в этом случае они применяются к типу, определяемому предшествующими спецификаторами. Повторения любого спецификатора в decl-specifier-seq , такие как const static const или virtual inline virtual являются ошибками , за исключением того, что long может появляться дважды (начиная с C++11) . ДеклараторыКаждый init-declarator в init-declarator-list S D1, D2, D3 ; обрабатывается так, как если бы он был отдельным объявлением с теми же спецификаторами: S D1 ; S D2 ; S D3 ; . Каждый декларатор вводит ровно один объект, ссылку, функцию или (для typedef-объявлений) псевдоним типа, чей тип задаётся decl-specifier-seq и опционально модифицируется операторами, такими как & (ссылка на) или [ ] (массив из) или ( ) (функция, возвращающая) в деклараторе. Эти операторы могут применяться рекурсивно, как показано ниже. Объявитель declarator может быть одним из следующих:
1)
Объявляемое
имя
.
2)
Декларатор, использующий
квалифицированный идентификатор
(
qualified-id
), определяет или переобъявляет ранее объявленный
член пространства имен
или
член класса
.
4)
Pointer declarator
: объявление
S
*
D
;
объявляет
D
как указатель на тип, определяемый
decl-specifier-seq
S
.
5)
Объявление указателя на член
: объявление
S C
::
*
D
;
объявляет
D
как указатель на член класса
C
типа, определяемого
decl-specifier-seq
S
.
nested-name-specifier
представляет собой
последовательность имён и операторов разрешения области видимости
::
6)
Декларатор lvalue-ссылки
: объявление
S
&
D
;
объявляет
D
как lvalue-ссылку на тип, определяемый
decl-specifier-seq
S
.
7)
Декларатор rvalue-ссылки
: объявление
S
&&
D
;
объявляет
D
как rvalue-ссылку на тип, определяемый
decl-specifier-seq
S
.
8)
Array declarator
.
noptr-declarator
любой допустимый декларатор, но если он начинается с *, &, или &&, он должен быть окружен круглыми скобками.
9)
Function declarator
.
noptr-declarator
любой допустимый декларатор, но если он начинается с *, &, или &&, он должен быть окружён круглыми скобками.
Он может заканчиваться необязательным завершающим возвращаемым типом.
(since C++11)
10)
Декларатор в скобках.
cv представляет собой последовательность const и volatile квалификаторов, где каждый квалификатор может встречаться в последовательности не более одного раза.
ПримечанияКогда block-declaration появляется внутри блока , и идентификатор, введённый объявлением, был ранее объявлен во внешнем блоке, внешнее объявление скрывается до конца блока. Если объявление вводит переменную с автоматической длительностью хранения, она инициализируется при выполнении оператора объявления. Все автоматические переменные, объявленные в блоке, уничтожаются при выходе из блока (независимо от того, как осуществляется выход: через исключение , goto , или по достижении его конца), в порядке, обратном порядку их инициализации. ПримерПримечание: этот пример демонстрирует, как некоторые сложные объявления разбираются с точки зрения грамматики языка. Другие популярные мнемонические правила: правило спирали , чтение изнутри наружу , и объявление отражает использование . Также существует автоматический парсер на https://cdecl.org .
Запустить этот код
#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)>); } Отчеты о дефектахСледующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам C++.
Смотрите также
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||