首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用variant记录的子类型访问实例化包时出现问题

使用variant记录的子类型访问实例化包时出现问题
EN

Stack Overflow用户
提问于 2021-05-03 22:54:57
回答 2查看 129关注 0票数 5

我尝试用Ada2012编译器编译Ada95程序。但是,通用包Garbage_Collector的实例化存在问题。包实例化中不接受子类型A_Term

代码语言:javascript
复制
prolog.adb:27:15: designated type of actual does not match that of formal "Link"
prolog.adb:27:15: instantiation abandoned

我曾尝试将A_Term更改为type A_Term is access A_Node;。然后,程序包将实例化,但其余代码会中断。从Ada 95开始有什么改变了吗?我如何让它在Ada 2012中工作?

代码语言:javascript
复制
procedure Prolog is

   generic
      type Item is limited private;
      type Link is access Item;
   package Garbage_Collector is
      procedure Get (L : in out Link) is null;
   end Garbage_Collector;

   type Node_Tag is (A, B);

   type Node (Tag : Node_Tag);
   type Term is access Node;

   type Node (Tag : Node_Tag) is
      record
         case Tag is
            when A => null;
            when B => null;
         end case;
      end record;

   subtype A_Node is Node (A);
   subtype A_Term is Term (A);
   package Gc_A is new Garbage_Collector
     (Item => A_Node,
      Link => A_Term);

   T : Term;
begin
   Gc_A.Get (T);
end Prolog;

代码来自斯坦福大学的Prolog模块。The project on GitHub

EN

回答 2

Stack Overflow用户

发布于 2021-05-04 23:36:03

我不能说到底是什么导致了你的错误。这很可能是一个编译器错误。为了以最小的侵入性方式解决这个问题,我建议使access关系对通用单元不可见:

代码语言:javascript
复制
procedure Prolog is

   generic
      type Item is limited private;
      type Link is private;
      with function Deref (L : Link) return Item is <>;
   package Garbage_Collector is
      procedure Get (L : in out Link) is null;
   end Garbage_Collector;

   type Node_Tag is (A, B);

   type Node (Tag : Node_Tag);
   type Term is access Node;

   type Node (Tag : Node_Tag) is
      record
         case Tag is
            when A => null;
            when B => null;
         end case;
      end record;

   subtype A_Node is Node (A);
   subtype A_Term is Term (A);
   
   function Deref (L : A_Term) return A_Node is (L.all);
   
   package Gc_A is new Garbage_Collector
     (Item  => A_Node,
      Link  => A_Term);

   T : Term;
begin
   Gc_A.Get (T);
end Prolog;

现在编译器没有抱怨,因为形式类型Link不再是一种访问类型,并且与Item没有关系。通过赋予函数Deref,您仍然能够取消对Link类型的对象的引用。如果你需要给它赋值,你需要一个额外的函数。

票数 5
EN

Stack Overflow用户

发布于 2021-05-04 01:20:50

在上面的代码示例中,声明了NodeTerm类型

代码语言:javascript
复制
type Node (Tag : Node_Tag);
type Term is access Node;

然后,您尝试声明两个子类型:

代码语言:javascript
复制
subtype A_Node is Node (A);
subtype A_Term is Term (A);

因为Node是一个判别式类型,所以声明subtype A_Node是有意义的。subtype A_Term的声明没有任何意义。Term类型为access Node,与Node类型不同。尝试将subtype A_Term的声明更改为:

代码语言:javascript
复制
subtype A_Term is access A_Node;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67371096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档