You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ada语言Visitor模式结合泛型的编译问题及实现方案咨询

实现Visitor设计模式时GNAT泛型类型报错问题

我在实现Visitor设计模式,部分元素计划通过泛型实现,但GNAT编译器对泛型类型报错。我已有一个泛型混入的解决方案,但该方案不够直观,想请教能否正确实现最初的方案,还是必须采用混入方案。

原始代码示例

visitors.ads

with ConcreteElements;
with Instantiation;

package Visitors is

  type Visitor_t is interface;

  procedure pVisit (this : in Visitor_t;
                    element : ConcreteElements.ConcreteElement_t) is abstract;

  procedure pVisit (this : in Visitor_t;
                    element : Instantiation.GenericElement_t) is abstract;

end Visitors;

elements.ads

limited with Visitors;

package Elements is

  type Element_t is abstract tagged null record;

  procedure pAccept
    (this : in Element_t;
     visitor : in Visitors.Visitor_t'Class) is abstract;

end Elements;

concreteelements.ads

limited with Visitors;
with Elements;

package ConcreteElements is

  type ConcreteElement_t is new Elements.Element_t with null record;

  overriding
  procedure pAccept
    (this : in ConcreteElement_t;
     visitor : in Visitors.Visitor_t'Class);

end ConcreteElements;

concreteelements.adb

with Visitors;

package body ConcreteElements is

  procedure pAccept
    (this : in ConcreteElement_t;
     visitor : in Visitors.Visitor_t'Class) is
  begin
    visitor.pVisit(this);
  end pAccept;

end ConcreteElements;

genericelements.ads

with Elements;
limited with Visitors;

generic
  type Parent_t (<>) is abstract new Elements.Element_t with private;
package GenericElements is

  type GenericElement_t is new Parent_t with null record;

  overriding
  procedure pAccept (this : in GenericElement_t;
                     visitor : in Visitors.Visitor_t'Class);

end GenericElements;

genericelements.adb

with Visitors;

package body GenericElements is

  procedure pAccept (this : in GenericElement_t;
                     visitor : in Visitors.Visitor_t'Class) is
  begin
    visitor.pVisit(this);
  end pAccept;

end GenericElements;

instantiation.ads

with GenericElements;
with Elements;

package instantiation is new GenericElements
  (Parent_t => Elements.Element_t);

编译器报错

编译器在genericelements.adb第9行报错:

expected type "instantiation.GenericELement_t" defined at genericelements.ads:8

found type "GenericElements.GenericElement_t" defined at genericelements.ads:8

我的混入式解决方案

修改后的相关代码如下:

修改后的visitors.ads

with ConcreteElements;
with Instantiation;

package Visitors is

  type Visitor_t is interface;

  procedure pVisit (this : in Visitor_t;
                    element : ConcreteElements.ConcreteElement_t) is abstract;

  procedure pVisit (this : in Visitor_t;
                    element : Instantiation.Instantiation_t) is abstract;

end Visitors;

修改后的genericelements.ads

with Elements;

generic
  type Parent_t (<>) is abstract new Elements.Element_t with private;
package GenericElements is

  type GenericElement_t is abstract new Parent_t with null record;

end GenericElements;

修改后的instantiation.ads

private with GenericElements;
limited with Visitors;
with Elements;

package instantiation is 

  type Instantiation_t is new Elements.Element_t with private;

  overriding
  procedure pAccept (this : in Instantiation_t;
                     visitor : Visitors.Visitor_t'Class);

private

  package instantiation_pck is new GenericElements 
    (Parent_t => Elements.Element_t);

  type Instantiation_t is new instantiation_pck.GenericElement_t with null record;

end instantiation;

修改后的instantiation.adb

with Visitors;

package body instantiation is

  procedure pAccept (this : in Instantiation_t;
                     visitor : Visitors.Visitor_t'Class) is
  begin
    visitor.pVisit(this);
  end pAccept;

end instantiation;

疑问

请问我能否正确实现第一种方案,还是必须采用混入方案?

内容的提问来源于stack exchange,提问作者Albatros23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 10:52:53