Spec-Zone.ru › Ada 2022
Справочник по Ada (Ada 2022)

12.6 Формальные подпрограммы

Формальные подпрограммы могут использоваться для передачи вызываемых сущностей в обобщенную единицу.

Синтаксис

formal_subprogram_declaration ::= formal_concrete_subprogram_declaration
| formal_abstract_subprogram_declaration
formal_concrete_subprogram_declaration ::=
with subprogram_specification [is subprogram_default]
[aspect_specification];
formal_abstract_subprogram_declaration ::=
with subprogram_specification is abstract [subprogram_default]
[aspect_specification];
subprogram_default ::= default_name | <> | null
default_name ::= name
Значение subprogram_default null не должно быть указано для формальной функции или для formal_abstract_subprogram_declaration.

Правила разрешения имен

Ожидаемый профиль для default_name, если он есть, – это профиль формальной подпрограммы.
Для формальной подпрограммы обобщенного типа ожидаемый профиль для фактической подпрограммы – это профиль формальной подпрограммы.

Правила легальности

Профили формального и любого именованного значения по умолчанию должны быть соответствовать типу параметров.
Профили формального и фактического значения должны соответствовать типу параметров.
Для типа параметра или результата formal_subprogram_declaration, имеющего явное null_exclusion:
  • если фактический, соответствующий formal_subprogram_declaration, статически обозначает формальную подпрограмму другого обобщенного блока G, а экземпляризация, содержащая фактический, происходит внутри тела обобщенного блока G или внутри тела обобщенного блока, объявленного в области объявления обобщенного блока G, то соответствующий параметр или тип результата формальной подпрограммы блока G должен иметь null_exclusion;
  • в противном случае тип соответствующего параметра или результата фактического значения, соответствующего formal_subprogram_declaration, должен исключать значение null. В дополнение к местам, где обычно применяются правила легальности (см. 12.3), это правило применяется также в частях сведений об экземпляре обобщенного блока.
Если именованное значение по умолчанию, если таковое имеется, является представлением с префиксом, то префикс этого представления должен обозначать объект, для которого разрешено переименование (см. 8.5.1). Аналогично, если фактическая подпрограмма в экземпляризации является представлением с префиксом, префикс этого представления должен обозначать объект, для которого разрешено переименование.
Если формальный параметр formal_abstract_subprogram_declaration имеет определенный тип T или анонимный тип доступа, указывающий на определенный тип T, то T называется управляющим типом formal_abstract_subprogram_declaration. Аналогично, если результат formal_abstract_subprogram_declaration для функции имеет определенный тип T или анонимный тип доступа, указывающий на определенный тип T, то T называется управляющим типом formal_abstract_subprogram_declaration. У formal_abstract_subprogram_declaration должен быть ровно один управляющий тип, и этот тип не должен быть неполным.
Фактическая подпрограмма для formal_abstract_subprogram_declaration должна быть:
  • диспетчерируемой операцией управляющего типа; или
  • если управляющий тип является формальным типом, а фактический тип, соответствующий этому формальному типу, – это конкретный тип T, то диспетчерируемой операцией типа T; или
  • если управляющий тип является формальным типом, а фактический тип – это тип класса T'Class, то неявно объявленная подпрограмма, соответствующая примитивной операции типа T (см. Статические семантики ниже).

Статические семантики

formal_subprogram_declaration объявляет формальную подпрограмму обобщения. Типы формальных параметров и результата (если есть) формальной подпрограммы определяются subtype_mark в formal_subprogram_declaration; однако, независимо от конкретных типов, обозначаемых subtype_marks, номинальные типы формальных параметров и результата (если есть) определяются как нестатические и не ограниченные, если они имеют тип массива (при вызове формальной подпрограммы нет применимых ограничений индексов). В экземпляре formal_subprogram_declaration объявляет представление фактического значения. Профиль этого представления получает типы и соглашения о вызовах из исходного профиля фактической сущности, а имена формальных параметров и default_expressions берутся из профиля, данного в formal_subprogram_declaration. Представление – это функция или процедура, но никогда не вход.
Если subtype_mark в профиле formal_subprogram_declaration обозначает формальный закрытый или формальный производный тип, а фактический тип для этого формального типа – это тип класса T'Class, то для целей разрешения соответствующей фактической подпрограммы в момент экземпляризации могут быть доступны некоторые неявные объявления следующим образом:
Для каждой примитивной подпрограммы типа T, которая непосредственно видна в момент экземпляризации и имеет по крайней мере один управляющий формальный параметр, потенциально доступна соответствующая неявно объявленная подпрограмма с тем же именем определения и тем же профилем, за исключением того, что T систематически заменяется T'Class в типах ее профиля. Тело такой подпрограммы определяется в 12.5.1 для примитивных подпрограмм формального типа, когда фактический тип – это тип класса.
Если у обобщенного блока есть subprogram_default указанный в виде поля, и соответствующий фактический параметр опущен, то это эквивалентно явному фактическому параметру, который является именем использования, идентичным имени определения формального.
Если у обобщенного блока есть subprogram_default указанный как зарезервированное слово null, и соответствующий фактический параметр опущен, то это эквивалентно явному фактическому параметру, который является нулевой процедурой, имеющей профиль, указанный в formal_subprogram_declaration.
Подпрограмма, объявленная formal_abstract_subprogram_declaration с управляющим типом T, является диспетчерируемой операцией типа T.
ПРИМЕЧАНИЕ 1 Правила сопоставления формальных подпрограмм задают требования, аналогичные требованиям к subprogram_renaming_declaration (см. 8.5.4). В частности, имя параметра формальной подпрограммы может отличаться от имени соответствующего параметра фактической подпрограммы; аналогично, для этих параметров могут быть разные default_expressions.
ПРИМЕЧАНИЕ 2 Ограничения, применяемые к параметру формальной подпрограммы, являются ограничениями соответствующего формального параметра соответствующей фактической подпрограммы (а не ограничениями, подразумеваемыми соответствующим subtype_mark в _specification формальной подпрограммы). Аналогичное замечание относится к результату функции. Поэтому для избежания путаницы рекомендуется использовать имя первого типа в любом объявлении формальной подпрограммы.
ПРИМЕЧАНИЕ 3 Тип, указанный для формального параметра обобщенной формальной подпрограммы, может быть любым видимым типом, включая обобщенный формальный тип того же generic_formal_part.
END_OF_DOCUMENT_MARKER
ПРИМЕЧАНИЕ 4 Формальная подпрограмма соответствует атрибуту типа, если атрибут является функцией с соответствующим определением. Литеральное значение перечисления данного типа соответствует безаргументной формальной функции, тип результата которой соответствует данному типу.
ПРИМЕЧАНИЕ 5 default_name обозначает сущность, которая видна или непосредственно видна в месте generic_declaration; ящик, используемый в качестве значения по умолчанию, эквивалентен имени, обозначающему сущность, которая непосредственно видна в месте generic_instantiation.
ПРИМЕЧАНИЕ 6 Фактическая подпрограмма не может быть абстрактной, если формальная подпрограмма является formal_abstract_subprogram_declaration (см. 3.9.3).
ПРИМЕЧАНИЕ 7 Подпрограмма, объявленная formal_abstract_subprogram_declaration, является абстрактной подпрограммой. Все вызовы подпрограммы, объявленной formal_abstract_subprogram_declaration, ограничены вызовами диспетчеризации. См. 3.9.3.
ПРИМЕЧАНИЕ 8 Процедура с нулевым значением в качестве значения по умолчанию для подпрограммы имеет соглашение Intrinsic (см. 6.3.1).

Примеры

Примеры формальных подпрограмм обобщения:
with function "+"(X, Y : Item) return Item is <>;
with function Image(X : Enum) return String is Enum'Image;
with procedure Update is Default_Update;
with procedure Pre_Action(X : in Item) is null; -- по умолчанию не выполняется никаких действий
with procedure Write(S : not null access Root_Stream_Type'Class;
Desc : Descriptor)
is abstract Descriptor'Write; -- см. 13.13.2
-- Операция диспетчеризации для Descriptor с значением по умолчанию
-- с учётом объявления обобщённой процедуры
generic
with procedure Action (X : in Item);
procedure Iterate(Seq : in Item_Sequence);
-- и процедуры
procedure Put_Item(X : in Item);
-- следующее создание возможно
procedure Put_List is new Iterate(Action => Put_Item);


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API