OK.Во-первых, я не вижу возможности, чтобы вы могли надеяться, что это сработает, если только процедуры, которые вы вызываете в пакете (-ах), не имеют одинакового профиля параметров, независимо от того, какой тип был использован.Как правило, универсальный пакет будет иметь по крайней мере одну подпрограмму, которая использует один из типов, с которыми вы создали его экземпляр в параметрах подпрограммы (или в качестве возвращаемого типа).
Если подпрограммы, которые вы хотите использовать, на самом деле имеют идентичныепрофили, я могу вспомнить пару вещей, которые вы могли бы сделать.Во-первых, используйте указатель на подпрограмму , которую вы хотите вызвать, и передайте ее.
type Init_Routine is access procedure ();
begin
main (ab.Init'access);
Во-вторых, все ваши универсальные пакеты будут содержать теговые типы, полученные изобщий родительский тип тега abstract
, в котором подпрограммы, которые вы хотите вызвать, определены как подпрограммы abstract
в родительском элементе.Если вы сделаете это, вы можете использовать динамическую диспетчеризацию для выбора между ними во время выполнения.
package Parent is
type Instance is abstract tagged null record;
type Dispatching_Instance_Ptr is access all Instance;
procedure Init (I : in out Instance) is abstract;
end Parent;
generic
--// Whatever your generic parameters are...
Package1 is
type Instance is new Parent.Instance with null record;
procedure Init (I : in out Instance);
...
end Package1;
--// (Package2 looks similar)
Переход к вызывающему коду:
Choice : Parent.Dispatching_Instance_Ptr;
begin
--// Let's assume the user "chooses" package aB
Choice := new'aB.Instance;
main (Choice);
... и для main:
procedure main(xx : in Parent.Dispatching_Instance_Ptr) is
begin
Parent.Init(xx.all); --// This should dynamic dispatch to the proper init routine
....
end main;
Примечание: я не запускал это через компилятор, поэтому, возможно, есть небольшие проблемы.Я уже нашел и исправил пару.