【发布时间】:2020-09-12 16:21:02
【问题描述】:
在 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,因此可能无法很好地扩展。
由于没有更好的术语,我将它们称为参数化子程序别名。
上述方法的一些问题:
- 仍然可以在调用 proc1、proc2 或 proc3 时覆盖 b。这是次要的,因为必须故意这样做(以及出于什么目的?)
- 它可能被认为通常不是 Ada 的做事方式(可能被认为是 C'ism),并且可能有更简洁的方式来使用泛型,但如果它涉及每个子程序的单独 ads/adb,那么对于上述这样一个简单的用例来说就太冗长了。
- 如果每个参数化子程序别名的方面变成几行,那么现在在维护期间需要更新更多,并且成为类似于需要每个参数化子程序别名的显式主体的维护问题。
所以我的问题是关于上述最后一点。
有没有办法将Import => True, Address => some_base'Address; 放入某种方面集,然后为每个参数化子程序别名重用它?
所以它会是这样的(aspect_set,using 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 的方法 做这样的事情。
【问题讨论】:
-
我不太清楚为什么以这种方式覆盖子程序让我不寒而栗!
-
我不确定这是便携的。使用添加或更改的参数默认值进行重命名(您在下面发现)是 Ada Way (TM)。