使用通用包

发布于 2024-11-05 13:38:58 字数 989 浏览 1 评论 0原文

我的问题很简单。我有 2 个通用包。我使用每个包两次(一次用于整数,一次用于字符串)。我有一个“主”文件,它使用用户选择的包。 - package1 带有整数 - 或带有字符串的 package1 - 或带有整数的 package2 - 或以字符串

procedure main is
     package aB is new package1(integer, false, afficheInteger, true);
    --package aB is new package1(Unbounded_String, true, afficheUnbounded, true);
    --package aB is new package2(1,integer, false, afficheInteger, true);
    --package aB is new package2(1, Unbounded_String, true, afficheUnbounded, true);

开头 的 package2 aB.init(); .....

目标是对 4 个包使用相同的代码(主要)。

不幸的是我找不到如何正确地做到这一点。目前,我列出了软件包列表,并对我不使用的软件包进行了评论。是否可以在开始时制作伪 if 或在开始时初始化包?也许在主函数中使用包参数?

非常感谢,对我的英语感到抱歉!

更新:

是否可以在函数中传递包参数?就像这样:

procedure init_paquetage1_int is
    package aB is new packA(integer, false, afficheInteger, true);
begin
    main(aB);
end init_paquetage1_int; 

procedure main(aB : packA) is
begin
    aB.init();
    ....
end main;

它不起作用。

my question is very simple. I have 2 generic package. I use each package 2 times (once for integers and strings for once). I have a "main" file that use the package selected by the user.
- package1 with integer
- or package1 with string
- or package2 with integer
- or package2 with string

procedure main is
     package aB is new package1(integer, false, afficheInteger, true);
    --package aB is new package1(Unbounded_String, true, afficheUnbounded, true);
    --package aB is new package2(1,integer, false, afficheInteger, true);
    --package aB is new package2(1, Unbounded_String, true, afficheUnbounded, true);

begin
aB.init();
.....

The goal is to use the same code (main) for the 4 packages.

Unfortunately I can't find how to do this properly. For the moment I put the list of packages and I comment the packages i don't use. Is it possible to make pseudo if in the begin or init the package in the begin ? Maybe with a package parameter in the main function ?

Thanks a lot and sorry for my english !

Update :

Is it possible to pass a package parameter in a function ? Like this :

procedure init_paquetage1_int is
    package aB is new packA(integer, false, afficheInteger, true);
begin
    main(aB);
end init_paquetage1_int; 

procedure main(aB : packA) is
begin
    aB.init();
    ....
end main;

It's not working.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧瑾黎汐 2024-11-12 13:38:58

好的。首先,我看不出有什么方法可以让它工作,除非您在包中调用的例程具有相同的参数配置文件,无论使用哪种类型。通常,通用包将至少有一个例程,该例程使用您在例程参数中实例化它的类型之一(或作为返回类型)。

如果您想要使用的例程实际上具有相同的配置文件,我可以想到您可以做的几件事。第一种是使用指向例程的指针< /a> 你想要调用,并将其传入。

   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;

注意:我还没有通过编译器运行它,所以可能存在一些小问题。我已经找到并修复了几个。

OK. First off, I don't see any way you could hope for this to work, unless the routines you are calling in the package(s) have the same parameter profile regardless of which type was used. Typically a generic package will have at least one routine that uses one of the types you instantiated it with in the routine's parameters (or as a return type).

If the routines you want to use do in fact have identical profiles, I can think of a couple of things you could do. The first is to use a pointer to the routine you want to call, and pass that in.

   type Init_Routine is access procedure ();
begin
   main (ab.Init'access);

The second would be to make your generic packages all contain tagged types derived from a common parent abstract tagged type that has the routines you want to call defined as abstract routines in the parent. If you do that, you can use dynamic dispatch to select between them at runtime.

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)

Skipping down to the calling code:

    Choice : Parent.Dispatching_Instance_Ptr;
begin
    --// Let's assume the user "chooses" package aB
    Choice := new'aB.Instance;
    main (Choice);

...and for 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;

Note: I haven't run this through a compiler, so there are probably minor issues. I've found and fixed a couple already.

南城旧梦 2024-11-12 13:38:58

每次实例化通用包时,它都会被视为单独的包。因此,您需要为每个实例化使用不同的包名称。

procedure main is
     package aA is new package1(integer, false, afficheInteger, true);
     package aB is new package1(Unbounded_String, true, afficheUnbounded, true);
     package aC is new package2(1,integer, false, afficheInteger, true);
     package aD is new package2(1, Unbounded_String, true, afficheUnbounded, true);
...

您现在可以将其中每一个用作单独的包。

aA.init();
aB.init();
...

您可以传入过程作为参数,但不能传入包。

如果您仍然对泛型感到困惑,我建议您阅读 http://en.wikibooks.org/ wiki/Ada_Programming/泛型

Each time you instantiate a generic package, it is treated as a separate package. Therefore, you need to use a different package name for each instantiation.

procedure main is
     package aA is new package1(integer, false, afficheInteger, true);
     package aB is new package1(Unbounded_String, true, afficheUnbounded, true);
     package aC is new package2(1,integer, false, afficheInteger, true);
     package aD is new package2(1, Unbounded_String, true, afficheUnbounded, true);
...

You can now use each of these as a separate package.

aA.init();
aB.init();
...

You can pass in procedures as parameters, but not packages.

If you're still confused on generics, I suggest you read http://en.wikibooks.org/wiki/Ada_Programming/Generics

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文