Ada Generic正式子程序

时间:2017-04-30 00:39:18

标签: generics tree procedure ada

我正在为学校做Ada任务。我的老师为我提供了以下代码。这是一个通用树。

generic
    type Item_Type is private;
    with procedure put(i : Item_Type);

我在测试文件中创建了一个新的通用树,就像这样。

package FrequencyTree is new Tree_Pkg (FrequencyRecord);
use FrequencyTree;

现在我收到以下错误。

treetest.adb:12:01: missing actual "put"
treetest.adb:12:01: in instantiation of "Tree_Pkg" declared at tree_pkg.ads:4
treetest.adb:12:01: instantiation abandoned

我知道我应该在某个地方以某种方式实现这个程序put,但在哪里以及如何?

2 个答案:

答案 0 :(得分:3)

提供的通用单元声明 一个formal type和一个formal subprogram,因此其通用instantiation要求两者一个实际的类型和实际的子程序。您的实际类型为FrequencyRecord;您的实际子程序应该是一个接受实际类型FrequencyRecord的参数的过程。然后,您可以使用所需的实际参数instantiate Tree_Pkg

type FrequencyRecord is …;

procedure Put(I : FrequencyRecord) is
begin
   …
end;

package FrequencyTree is new Tree_Pkg (FrequencyRecord, Put);

附录:如上所述herehere,实际子程序的概况必须符合正式子程序的概况,但名称可能不同。

答案 1 :(得分:2)

在研究trashgod's answer之后,在何处以及如何考虑以下方面:

package FrequencyTree is new Tree_Pkg
  (Item_Type => FrequencyRecord, 
   Put       => YourOwnPut);

在进行此实例化之前必须存在FrequencyRecordYourOwnPut必须存在:Ada编译器从头到尾读取您的Ada文本,因此当它看到实例化时,它一定见过这两个。

此要求意味着您要在实例化YourOwnPut之前在文本行上定义Tree_Pkg,以使实例化行之前存在类型FrequencyRecord和过程YourOwnPut 。或者,也许选择一些替代安排:例如,如果FrequencyRecordYourOwnPut可以放在一个单独的包中,那么你在上下文中 那个包任何编译单元的子句围绕您的实例化行。 (根据错误消息判断,它可能被称为Treetest。)说,

with Frequency_Stuff;

...
   package FrequencyTree is new Tree_Pkg
     (Item_Type => Frequency_Stuff.FrequencyRecord, 
      Put       => Frequency_Stuff.YourOwnPut);

因此,当您执行实例化时,编译器已经看到并编译了包Frequency_Stuff。 IOW,如果您Frequency_Stuff.FrequencyRecord Item_Type的实际参数和Frequency_Stuff.YourOwnPut Put的实际参数,那么这些实际参数已经存在。