Справочник Ada 2005
12.1 Обобщённые объявления
Объявление generic_declaration объявляет обобщённый блок, который может быть обобщённой подпрограммой или обобщённым пакетом. Объявление generic_declaration включает в себя generic_formal_part, объявляющий любые обобщённые формальные параметры. Обобщённый формальный параметр может быть объектом; альтернативно (в отличие от параметра подпрограммы), он может быть типом, подпрограммой или пакетом.
Синтаксис
generic_formal_parameter_declaration ::=
formal_object_declaration
| formal_type_declaration
| formal_subprogram_declaration
| formal_package_declaration
formal_object_declaration
| formal_type_declaration
| formal_subprogram_declaration
| formal_package_declaration
Единственная форма subtype_indication, разрешенная в generic_formal_part, — это subtype_mark (т.е. subtype_indication не должна включать явного constraint). Имя обобщённой подпрограммы должно быть идентификатором (identifier), а не символом оператора (operator_symbol).
Статическая семантика
Объявление generic_declaration объявляет обобщённый блок — обобщённый пакет, обобщённую процедуру или обобщённую функцию.
Сущность является обобщённой формальной сущностью, если она объявлена в generic_formal_parameter_declaration. «Обобщённый формальный» или просто «формальный» используется в качестве префикса при ссылке на объекты, подтипы (и типы), функции, процедуры и пакеты, которые являются обобщёнными формальными сущностями, а также на соответствующие их объявления. Примеры: «обобщённая формальная процедура» или «формальное объявление целого типа».
Динамическая семантика
Выполнение объявления generic_declaration не имеет эффекта.
ПРИМЕЧАНИЯ
1 Вне обобщённого блока имя, обозначающее generic_declaration, обозначает обобщённый блок. В противоположность этому, внутри области объявления обобщённого блока имя, обозначающее generic_declaration, обозначает текущий экземпляр.
2 Внутри обобщённого тела подпрограммы (subprogram_body) имя этого блока действует как имя подпрограммы. Следовательно, это имя может быть перегружено и может появляться в рекурсивном вызове текущего экземпляра. По той же причине это имя не может появиться после зарезервированного слова new в (рекурсивной) generic_instantiation.
3 default_expression или default_name, появляющиеся в generic_formal_part, не вычисляются во время выполнения generic_formal_part; вместо этого, они вычисляются при использовании. (Применяются обычные правила видимости для любого имени, используемого в выражении: объявление, на которое ссылается имя, поэтому должно быть видимо в месте выражения.)
Примеры
Примеры обобщённых формальных частей:
generic -- без параметров
generic
Size : Natural; -- формальный объект
Size : Natural; -- формальный объект
generic
Length : Integer := 200; -- формальный объект с выражением по умолчанию
Length : Integer := 200; -- формальный объект с выражением по умолчанию
Area : Integer := Length*Length; -- формальный объект с выражением по умолчанию
generic
type Item is private; -- формальный тип
type Index is (<>); -- формальный тип
type Row is array(Index range <>) of Item; -- формальный тип
with function "<"(X, Y : Item) return Boolean; -- формальная подпрограмма
type Item is private; -- формальный тип
type Index is (<>); -- формальный тип
type Row is array(Index range <>) of Item; -- формальный тип
with function "<"(X, Y : Item) return Boolean; -- формальная подпрограмма
Примеры обобщённых объявлений, объявляющих обобщённые подпрограммы Exchange и Squaring:
generic
type Elem is private;
procedure Exchange(U, V : in out Elem);
type Elem is private;
procedure Exchange(U, V : in out Elem);
generic
type Item is private;
with function "*"(U, V : Item) return Item is <>;
function Squaring(X : Item) return Item;
type Item is private;
with function "*"(U, V : Item) return Item is <>;
function Squaring(X : Item) return Item;
Пример обобщённого объявления, объявляющего обобщённый пакет:
generic
type Item is private;
type Vector is array (Positive range <>) of Item;
with function Sum(X, Y : Item) return Item;
package On_Vectors is
function Sum (A, B : Vector) return Vector;
function Sigma(A : Vector) return Item;
Length_Error : exception;
end On_Vectors;
type Item is private;
type Vector is array (Positive range <>) of Item;
with function Sum(X, Y : Item) return Item;
package On_Vectors is
function Sum (A, B : Vector) return Vector;
function Sigma(A : Vector) return Item;
Length_Error : exception;
end On_Vectors;