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
相关产品推荐
相关产品推荐

