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

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), это правило применяется также в закрытой части экземпляра генерической единицы.
Если формальный параметр 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 должна быть операцией диспетчеризации контролирующего типа или фактического типа, соответствующего контролирующему типу.

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

formal_subprogram_declaration объявляет генерическую формальную подпрограмму. Типы формальных параметров и результата, если таковые имеются, формальной подпрограммы определяются метками подтипов subtype_mark, заданными в formal_subprogram_declaration; однако, независимо от конкретных подтипов, обозначаемых метками subtype_mark, номинальные подтипы формальных параметров и результата, если таковые имеются, определяются как нестатические и неявные, если они имеют тип массива (никакое применимое ограничение индекса не предоставляется при вызове формальной подпрограммы). В экземпляре formal_subprogram_declaration объявляет представление фактического значения. Профиль этого представления берёт подтипы и соглашение о вызове из исходного профиля фактической сущности, а имена формальных параметров и значения по умолчанию default_expression берутся из профиля, заданного в formal_subprogram_declaration. Представление является функцией или процедурой, но никогда не является входом.
Если метка подтипа subtype_mark в профиле formal_subprogram_declaration обозначает формальный частный или формальный производный тип, а фактический тип для этого формального типа является классовым типом T'Class, то для целей разрешения соответствующей фактической подпрограммы в момент инстанцирования доступны некоторые неявные объявления как возможные решения следующим образом:
Для каждой примитивной подпрограммы типа T, которая непосредственно видна в момент инстанцирования и у которой есть хотя бы один контролирующий формальный параметр, соответствующая неявно объявленная подпрограмма с тем же именем определения и тем же профилем, что и примитивная подпрограмма, за исключением того, что T систематически заменяется на T'Class в типах её профиля, потенциально доступна для использования. Тело такой подпрограммы определяется в 12.5.1 для примитивных подпрограмм формального типа, когда фактический тип является классовым.
Если генерическая единица имеет subprogram_default, заданный в виде поля, и соответствующий фактический параметр опущен, то это эквивалентно явному фактическому параметру, который является именем использования, идентичным имени определения формального параметра.
Если генерическая единица имеет subprogram_default, заданный зарезервированным словом null, и соответствующий фактический параметр опущен, то это эквивалентно явному фактическому параметру, который является процедурой null, имеющей профиль, указанный в formal_subprogram_declaration.
Подпрограмма, объявленная formal_abstract_subprogram_declaration с контролирующим типом T, представляет собой операцию диспетчеризации типа T.
ПРИМЕЧАНИЯ
13 Правила сопоставления формальных подпрограмм содержат требования, аналогичные требованиям, предъявляемым к subprogram_renaming_declaration (см. 8.5.4). В частности, имя параметра формальной подпрограммы не обязательно должно совпадать с именем соответствующего параметра фактической подпрограммы; аналогично, для этих параметров default_expression не обязательно должны соответствовать друг другу.
14 Ограничения, применяемые к параметру формальной подпрограммы, являются ограничениями соответствующего формального параметра сопоставляемой фактической подпрограммы (а не теми, которые подразумеваются соответствующей subtype_mark в спецификации формальной подпрограммы). Аналогичное замечание относится к результату функции. Поэтому, для избежания путаницы, рекомендуется использовать имя первого подтипа в любом объявлении формальной подпрограммы.
15 Подтип, указанный для формального параметра генерической формальной подпрограммы, может быть любым видимым подтипом, включая генерический формальный подтип той же самой generic_formal_part.
16 Формальная подпрограмма сопоставляется с атрибутом типа, если атрибут является функцией с соответствующей спецификацией. Элемент перечисления данного типа сопоставляется с безаргументной формальной функцией, тип результата которой является заданным типом.
17 default_name обозначает сущность, которая видна или непосредственно видна в месте generic_declaration; поле, используемое в качестве значения по умолчанию, эквивалентно имени, обозначающему сущность, которая непосредственно видна в месте _instantiation.
END_OF_DOCUMENT_MARKER
18 Фактическая подпрограмма не может быть абстрактной, если формальная подпрограмма является formal_abstract_subprogram_declaration (см. 3.9.3).
19 Подпрограмма, объявленная с помощью formal_abstract_subprogram_declaration, является абстрактной подпрограммой. Все вызовы подпрограммы, объявленной с помощью formal_abstract_subprogram_declaration, должны быть вызовами с диспетчеризацией. См. 3.9.3.
20 Нулевая процедура в качестве значения по умолчанию подпрограммы имеет соглашение 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