有没有一种方法可以在Ada特别是GNAT中创建和重用方面集?

问题描述

在C / C ++中,我经常使用预处理器来定义基于通用基本过程的过程(是的,我知道,C语言中的函数)。

例如(名称,类型和值是假设的):

// in some .h file
void some_base_procedure(int a,char c);

#define proc1(a) some_base_procedure(a,'d')
#define proc2(a) some_base_procedure(a,'e')
#define proc3(a) some_base_procedure(a,'f')

我已经研究了Ada中的泛型并将其用于程序包,但是对于子程序,我不确定如何干净地执行类似于上述C示例的操作。

但是我确实提出了这个建议:

-- in some .ads file
procedure some_base(a:integer; c: character);

procedure proc1(a:integer; b: character := 'd') with
  Import    => True,Address   => some_base'Address;
procedure proc2(a:integer; b: character := 'e') with
  Import    => True,Address   => some_base'Address;
procedure proc3(a:integer; b: character := 'f') with
  Import    => True,Address   => some_base'Address;

这实际上工作得很好,我只需要在相关的.adb文件中为some_base实现一个主体,就不必实现仅使用正确的参数值调用some_base的proc1,proc2,proc3子程序主体。在我的一些用例中,尽管我还有其他方面,但仅是Import和Address,所以可能无法很好地扩展。

由于缺少更好的术语,我将其称为带参数的子程序别名

上述方法的一些问题:

  1. 在对proc1,proc2或proc3的调用中,仍然可以覆盖b。这是次要的,因为必须有意地这样做(出于什么目的?)
  2. 可以认为它通常不是Ada的做事方式 (可能被视为C'ism),并且可能有更干净的方法来使用泛型,但如果每个子程序涉及一个单独的ads / adb,那么对于如上所述的这种简单用例而言,这太冗长了。
  3. 如果每个参数化子程序别名的各个方面变为几行,则现在在维护期间需要更新的内容更多,并成为与维护问题类似的维护问题,因为每个参数化子程序别名都需要显式主体

所以我的问题是关于以上最后一点。

是否有某种方法可以将Import => True,Address => some_base'Address;放入某种方面集,然后将其重新用于每个参数化的子程序别名

这样会是这样( aspect_set 使用some_base_set ,...组成了此示例):

-- in some .ads file
procedure some_base(a:integer; c: character);
aspect_set some_base_set is Import    => True,Address   => some_base'Address;

procedure proc1(a:integer; b: character := 'd') using some_base_set;
procedure proc2(a:integer; b: character := 'e') using some_base_set;
procedure proc3(a:integer; b: character := 'f') using some_base_set;

即使没有,我也认为我的上述方法足够好,除非有人有说服力地指出为什么这是一种非常糟糕的方法,并且还有一种更具表现力的 Ada方式 做这样的事情。

解决方法

深入研究之后,我找到了一个更通用的解决方案。

-- in some .ads file
procedure some_base(a:integer; c: character);
procedure proc1(a:integer; b: character := 'd') renames some_base;
procedure proc2(a:integer; b: character := 'e') renames some_base;
procedure proc3(a:integer; b: character := 'f') renames some_base;

这比我使用的要干净,尽管仍然可以覆盖默认值,但这是次要的。它解决了维护问题,这首先就是问题的全部重点。

,

泛型有什么问题?

generic
   C : Character;
procedure Some_Base(A : Integer);

procedure Some_Base(A : Integer) is
begin
   -- do something with A and B;
end Some_Base;


procedure Proc_1 is new Some_Base('d');
procedure Proc_2 is new Some_Base('e');
procedure Proc_3 is new Some_Base('f');

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...