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

12.3 Генерация экземпляров

Экземпляр обобщённого блока объявляется с помощью generic_instantiation.

Синтаксис

generic_instantiation ::=
package defining_program_unit_name is
new generic_package_name [generic_actual_part];
| procedure defining_program_unit_name is
new generic_procedure_name [generic_actual_part];
| function defining_designator is
new generic_function_name [generic_actual_part];
generic_actual_part ::=
(generic_association {, generic_association})
generic_association ::=
[generic_formal_parameter_selector_name =>] explicit_generic_actual_parameter
explicit_generic_actual_parameter ::= expression | variable_name
| subprogram_name | entry_name | subtype_mark
| package_instance_name
Ассоциация generic_association является именованной или позиционной в зависимости от того, указано ли generic_formal_parameter_selector_name. Все позиционные ассоциации должны предшествовать именованным.
Фактический параметр обобщения — это либо explicit_generic_actual_parameter, указанный в generic_parameter_association для каждого формального параметра, либо соответствующее значение default_expression или default_name, если для формального параметра не указана generic_parameter_association. Когда смысл понятен из контекста, термин «фактический параметр обобщения» или просто «фактический параметр» используется как синоним для «фактического параметра обобщения», а также для значения этого параметра.

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

В generic_instantiation для конкретного типа программного блока (пакет, процедура или функция), имя должно обозначать обобщённый блок соответствующего типа (обобщённый пакет, обобщённая процедура или обобщённая функция, соответственно).
generic_formal_parameter_selector_name ассоциации generic_association должен обозначать generic_formal_parameter_declaration обобщённого блока, который экземплифицируется. Если у двух или более формальных подпрограмм одинаковое имя, то для соответствующих фактических параметров не разрешены именованные ассоциации.
generic_instantiation должен содержать не более одной generic_association для каждого формального параметра. Каждый формальный параметр без ассоциации должен иметь default_expression или subprogram_default.
В обобщённом блоке правила легальности проверяются во время компиляции generic_declaration и тела обобщённого блока, учитывая свойства формальных параметров. В видимой части и части формальных параметров экземпляра правила легальности проверяются во время компиляции generic_instantiation, учитывая свойства фактических параметров. В других частях экземпляра правила легальности не проверяются; это правило не применяется, когда данное правило явно это не предусматривает.

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

generic_instantiation объявляет экземпляр; он эквивалентен объявлению экземпляра (package_declaration или subprogram_declaration) сразу после тела экземпляра, в месте экземплификации.
Экземпляр является копией шаблона. Каждое использование формального параметра становится (в копии) использованием фактического, как объяснено ниже. Экземпляр обобщённого пакета — это пакет, обобщённой процедуры — процедура, а обобщённой функции — функция.
Интерпретация каждого конструкта в обобщённом объявлении или теле определяется с использованием правил перегрузки при компиляции этого обобщённого объявления или тела. В экземпляре интерпретация каждого (скопированного) конструкта такая же, за исключением случаев имени, которое обозначает generic_declaration или какое-либо объявление внутри обобщённого блока; соответствующее имя в экземпляре затем обозначает соответствующую копию объявленного объявления. Правила перегрузки не применяются в экземпляре.
В экземпляре generic_formal_parameter_declaration объявляет представление, свойства которого идентичны свойствам фактического, за исключением случаев, указанных в 12.4, «Формальные объекты» и 12.6, «Формальные подпрограммы». Аналогично, для объявления внутри generic_formal_parameter_declaration, соответствующее объявление в экземпляре объявляет представление, свойства которого идентичны соответствующему объявлению в объявлении фактического.
Неявные объявления также копируются, и имя, которое обозначает неявное объявление в обобщении, обозначает соответствующую копию в экземпляре. Однако для типа, объявленного в видимой части обобщения, для использования вне экземпляра неявным образом объявляется целый новый набор примитивных подпрограмм, и он может отличаться от скопированного набора, если свойства типа каким-либо образом зависят от свойств типа, указанного в экземпляре. Например, если тип в обобщении получен от формального частного типа, то в экземпляре тип унаследует подпрограммы от соответствующего фактического типа.
Эти новые неявные объявления появляются сразу после объявления типа в экземпляре и переопределяют скопированные. Скопированные могут вызываться только изнутри экземпляра; новые — только извне экземпляра, хотя для тегированных типов тело нового может быть выполнено вызовом старого.
В видимой части экземпляра явное объявление переопределяет неявное объявление, если они являются омографами, как описано в 8.3. С другой стороны, явное объявление в частной части экземпляра переопределяет неявное объявление в экземпляре только в том случае, если соответствующее явное объявление в обобщении переопределяет соответствующее неявное объявление в обобщении. Соответствующие правила применяются к другим видам переопределения, описанным в 8.3.

Правила после компиляции

Рекурсивная генерация экземпляров не допускается в следующем смысле: если данный обобщённый блок включает экземплификацию второго обобщённого блока, то экземпляр, сгенерированный этой экземплификацией, не должен включать экземпляр первого обобщённого блока (будь то прямой или косвенный экземпляр через промежуточные экземплификации).

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

Для обработки generic_instantiation, каждый generic_association сначала вычисляется. Если используется значение по умолчанию, подразумевается неявный generic_association для этого правила. Эти вычисления выполняются в произвольном порядке, за исключением случаев, когда вычисление фактического параметра по умолчанию выполняется после вычисления другого фактического параметра, если значение по умолчанию включает имя, которое обозначает другой параметр. Наконец, обрабатываются объявление и тело экземпляра.
Для вычисления generic_association фактический параметр обобщения вычисляется. Дополнительные действия выполняются в случае формального объекта в режиме in (см. 12.4).
ПРИМЕЧАНИЯ
5 Если формальный тип не тегирован, то тип рассматривается как нетегированный тип в теле обобщения. Наследование от такого типа в теле обобщения разрешено; новый тип не получает нового значения тега, даже если фактический тип тегирован. Операции переопределения для такого производного типа не могут быть отправлены извне экземпляра.

Примеры

Примеры экземплификаций обобщений (см. 12.1):
procedure Swap is new Exchange(Elem => Integer);
procedure Swap is new Exchange(Character); -- Swap перегружен
function Square is new Squaring(Integer); -- "*" для Integer используется по умолчанию
function Square is new Squaring(Item => Matrix, "*" => Matrix_Product);
function Square is new Squaring(Matrix, Matrix_Product); -- то же самое, что и предыдущее
package Int_Vectors is new On_Vectors(Integer, Table, "+");
Примеры использования экземплифицированных блоков:
Swap(A, B);
A := Square(A);
T : Table(1 .. 5) := (10, 20, 30, 40, 50);
N : Integer := Int_Vectors.Sigma(T); -- 150 (см. 12.2, «Общие тела» для тела Sigma)
использовать Int_Vectors;
M : Integer := Sigma(T); -- 150


Spec-Zone.ru

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