Generics 有没有办法在Ada中创建和重用方面集(特别是GNAT)?
在C/C++中,我经常使用预处理器来定义基于公共基过程的过程(是的,我知道,C中的函数) 例如(名称、类型和值是假设的):Generics 有没有办法在Ada中创建和重用方面集(特别是GNAT)?,generics,ada,gnat,Generics,Ada,Gnat,在C/C++中,我经常使用预处理器来定义基于公共基过程的过程(是的,我知道,C中的函数) 例如(名称、类型和值是假设的): //在某个.h文件中 取消一些基本程序(int a,char c); #定义proc1(a)一些基本过程(a,‘d’) #定义proc2(a)一些基本程序(a,‘e’) #定义proc3(a)一些基本程序(a,‘f’) 我已经研究了Ada中的泛型,并将它们用于包,但对于子程序,我不确定如何干净地执行类似于上述C示例的操作 然而,我确实想到了这个: -- in some .
//在某个.h文件中
取消一些基本程序(int a,char c);
#定义proc1(a)一些基本过程(a,‘d’)
#定义proc2(a)一些基本程序(a,‘e’)
#定义proc3(a)一些基本程序(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文件中的某个_基实现一个body,而不必实现只调用具有正确参数值的某个_基的proc1、proc2、proc3子程序body。在我的一些用例中,虽然我有更多的方面,但只是导入和寻址,所以这可能无法很好地扩展
由于缺少更好的术语,我将这些称为参数化子程序别名
上述方法存在一些问题:
Import=>True,Address=>some_base'Address将>编码到某种方面集,然后对每个参数化子程序别名重用它
所以它应该是这样的(aspect_set,使用一些基本集,…为这个例子制作):
即使没有,我认为我的上述方法是好的,除非有人能令人信服地指出为什么它是一个非常糟糕的方法,并且有一个更具表现力的<艾达>类似的方式< /强>这样做。
在深入研究之后,我发现了一个更一般的解决方案。
-- 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');
我不太清楚为什么以这种方式叠加子程序会让我不寒而栗!我不确定这是不是便携式的。使用添加或更改的参数默认值重命名,您在下面发现的是,并且是Ada Way(TM)。在一个.adb文件中也许我能做到?但我不能将某个_库的主体放在.adb文件中,而在.ads文件中则是一个通用原型,除非得到警告:不能在看到主体之前实例化“某个_库”。我希望所有派生过程都在同一个.ads文件中定义。有些库可以是自己的。ads和.adbI可以让泛型像你说的那样工作,我只是不让它们在我的用例中工作,在我的用例中,最终派生函数正在设置其他默认值(例如使用GNAT.Source\u Info时,它与“重命名”一起工作)方法。好的,只需使用一些_Base就可以了…无需重命名、实例化或导入。使用泛型函数为包层次结构增加了一些复杂性,但这很好。以前我只使用package1.ads和package1.adb。现在我有package1.ads、package2.ads、Base _procedure.ads、Base _procedure.adb.Base _procedure使用s package1,package2使用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');