无法访问Ada泛型参数的成员

无法访问Ada泛型参数的成员,ada,Ada,我正在尝试编写一个通用包,所需的操作之一是对通过总线接收的数据记录进行校验和。记录类型会有所不同,它是一个通用参数。但是,任何访问泛型参数成员的尝试都会导致编译错误 错误。。。(Ada 95蚊虫2009) 宣言 generic type The_Transfer_Type is private; SIZE : Integer; package CC_Test_Channel is function Checksum(Msg : The_Transfer_Type) return In

我正在尝试编写一个通用包,所需的操作之一是对通过总线接收的数据记录进行校验和。记录类型会有所不同,它是一个通用参数。但是,任何访问泛型参数成员的尝试都会导致编译错误

错误。。。(Ada 95蚊虫2009)

宣言

generic
  type The_Transfer_Type is private;
  SIZE : Integer;
package CC_Test_Channel is
  function Checksum(Msg : The_Transfer_Type) return Integer;
end package
而尸体

function Checksum(Msg : The_Transfer_Type) return Integer is
  Sum : Integer := 0;
begin
  -- calculate the checksum
  for i in 1 .. SIZE loop
    Sum := Sum + Integer(Msg.Data(i));
  end loop;
  return Sum;
end Checksum;

当您指定泛型参数是私有类型时,Ada假定您的意思是:-)

即,您无法访问其组件。Ada不是“”,所以您是否知道实例化类型实际上可能拥有特定字段是无关紧要的。(如果_Transfer_Type参数被实例化为整数,那么您希望校验和函数如何工作?)

解决此问题的一种方法是,还向泛型提供一个访问器函数作为参数,该泛型将检索计算校验和所需的数据。例如:

generic
   type The_Transfer_Type is private;
   with function Get_Checksummable_Data_Item
           (Msg : The_Transfer_Type;
            I   : Integer) return Integer;
   SIZE : Integer;

package CC_Test_Channel is
   function Checksum(Msg : The_Transfer_Type) return Integer;
end CC_Test_Channel;
然后,主体是:

function Checksum(Msg : The_Transfer_Type) return Integer is
   Sum : Integer := 0;
begin
   -- calculate the checksum
   for i in 1 .. SIZE loop
      Sum := Sum + Get_Checksummable_Data(Msg, I);
   end loop;
   return Sum;
end Checksum;
然后,为Get_Checksummable_数据提供的函数特定于_Transfer_类型,并从_Transfer_类型的组件字段返回所选值

还有很多其他的方法可以设置它,比如提供一个无约束的数组类型作为一个通用的形式参数和一个形式函数来检索它——这也允许您去掉显式的SIZE形式参数。或者,您可以编写一个Checksum()函数,作为实例化CC_Test_通道的类型上的操作之一,然后执行以下操作:

with function Calculate_Checksum(Msg : The_Transfer_Type) return Integer;
作为一般形式之一

退后一步,考虑一下可能性

generic 
  type The_Transfer_Type is private; 
  ...
上面的代码意味着客户机可以为_Transfer_类型提供他们梦想的任何类型(只要它不是“受限的”)。这也意味着你的泛型完全不知道这个类型,除了一个符号是可用的

对于Ada泛型,可以为泛型参数提供多少种不同类型的对象,以及泛型可以对这些对象执行哪些操作,这两者之间存在某种相反的关系。例如,最开放的类型是
is limited private
。你可以为其中一个提供任何类型的Whatshover。然而,泛型对它几乎无能为力。甚至连任务都没有

去掉“limited”后,您可以使用它做一些调整,但只能提供可以指定的类型。另一方面,您可以将其定义为:
类型\u Transfer\u类型为()
,然后您可以提供任何整数或枚举类型,并将首先获得类似
”的内容。更进一步说,您可以执行
类型\u Transfer\u类型为range
,并且您可以获得执行整数数学运算的能力,但只能提供整数数字类型。

(从注释中移动,因为它变长了)

Ada(95及更高版本)支持流。与C++流不同,它非常适合字符串转换,<强>艾达流是指在数据< /强>(通常I/O)上执行操作的一般机制。p> 每个Ada对象都有
'Write
'Read
属性。有一些语言提供的流(用于文件I/O),但您也可以通过派生来创建自己的流。如果您以这种方式编写自己的流,那么有一些低级例程可以让您直接访问数据


这允许您编写自己的流来执行操作,如I/O、数据压缩,,或者在您的情况下,在将数据加载到变量(通过“读取”)之前,对来自总线的数据进行校验和。过去我自己做过,为我们的实时软件实现了录制/回放功能。我也研究过一次压缩(我们最终不需要压缩)。

只要他退后一步,可能就值得考虑使用流操作获取他想要的数据……这就是我采用的解决方案。什么是流操作?答案有点长,我决定它需要格式化,所以我把它移到下面的第二个答案中。嗯,我看到了很多关于流/压缩的潜力。你有一个例子要贴吗?如果是这样的话,我会非常感兴趣的。@Shark8-不幸的是,没有。我曾经亲自使用自定义流为模拟器记录/回放系统实现数据快照和恢复,但这是专有代码。我曾经在百灵鸟上研究过使用streams为Ada实现一个自由软件压缩库,但并没有取得很大进展。虽然之前我已经做过上述工作,但我相信这是完全可行的。我在某处找到了一本Ada[83]的书,我相信是Booch写的,书中有一些关于“管道”IIRC的有趣结构。。。我不知道我把它放哪儿了。
generic 
  type The_Transfer_Type is private; 
  ...