相互依赖的类型声明和Ada.Containers
在“盒式类型”(对于解释器)的实现中,我最初在子包中有向量,并使用System.Access_到_地址_的转换来根据需要从System.Address到Vector_Ptr进行转换,以避免循环依赖性中看似无法克服的问题。(至少,没有使用limited with every对我起到了作用。)它起了作用,但看起来像是一个讨厌的黑客。所以我决定将容器类型放入主包类型中。Boxed。现在GNAT抱怨“第12行定义的不完整类型“Vector”的可见部分没有声明” 有办法解决这个问题吗?还是我应该回到我讨厌的黑客 Ada 2005使用GNAT 4.6和标志-gnat05相互依赖的类型声明和Ada.Containers,ada,recursive-datastructures,Ada,Recursive Datastructures,在“盒式类型”(对于解释器)的实现中,我最初在子包中有向量,并使用System.Access_到_地址_的转换来根据需要从System.Address到Vector_Ptr进行转换,以避免循环依赖性中看似无法克服的问题。(至少,没有使用limited with every对我起到了作用。)它起了作用,但看起来像是一个讨厌的黑客。所以我决定将容器类型放入主包类型中。Boxed。现在GNAT抱怨“第12行定义的不完整类型“Vector”的可见部分没有声明” 有办法解决这个问题吗?还是我应该回到我讨厌
with Interfaces; use Interfaces;
with Ada.Strings.Wide_Unbounded; use Ada.Strings.Wide_Unbounded;
with Ada.Containers.Vectors;
with Green_Tasks; use Green_Tasks;
package Types.Boxed is
type Type_T is (T_Null, T_Unsigned_64, T_String, T_Boolean,
T_Green_Task, T_Vector);
type String_Ptr is access all Unbounded_Wide_String;
type Vector;
type Vector_Ptr is access all Vector;
type Item (IType : Type_T := T_Null) is record
case IType is
when T_Null => null;
when T_Unsigned_64 => Value_Unsigned_64 : Unsigned_64;
when T_String => Value_String : String_Ptr;
when T_Boolean => Value_Boolean : Boolean;
when T_Green_Task => Value_Green_Task : Green_Task_Ptr;
when T_Vector => Value_Vector : Vector_Ptr;
end case;
end record;
procedure Free (Datum : in out Item);
procedure Box (Datum : out Item; Value : in Unsigned_64);
function Unbox (Datum : Item) return Unsigned_64;
procedure Box (Datum : out Item; Value : String_Ptr);
function Unbox (Datum : Item) return String_Ptr;
procedure Box (Datum : out Item; Value : in Boolean);
function Unbox (Datum : Item) return Boolean;
procedure Box (Datum : out Item; Value : in Green_Task_Ptr);
function Unbox (Datum : Item) return Green_Task_Ptr;
function Get_Boxed_Type (Datum : Item) return Type_T;
-- vectors
package Item_Vectors is new Ada.Containers.Vectors
( Index_Type => Natural,
Element_Type => Item
);
use Item_Vectors;
function Vector_New (Size_Hint : Positive) return Item;
function Unbox (Datum : Item) return Vector_Ptr;
procedure Vector_Free (V : in out Vector_Ptr);
function Vector_Copy (V : Vector_Ptr) return Item;
pragma Inline (Box);
pragma Inline (Unbox);
pragma Pure_Function (Unbox);
pragma Pure_Function (Get_Boxed_Type);
end Types.Boxed;
我仔细研究了一下,发现我可以通过制作元素类型
Item\u Ptr
的Item\u向量来编译它:
type Item (<>);
type Item_Ptr is access all Item;
package Item_Vectors is new Ada.Containers.Vectors
( Index_Type => Natural,
Element_Type => Item_Ptr
);
subtype Vector is Item_Vectors.Vector;
type Vector_Ptr is access all Vector;
type Item (IType : Type_T := T_Null) is record
case IType is
when T_Null => null;
when T_Unsigned_64 => Value_Unsigned_64 : Unsigned_64;
when T_String => Value_String : String_Ptr;
when T_Boolean => Value_Boolean : Boolean;
when T_Vector => Value_Vector : Vector_Ptr;
end case;
end record;
类型项();
类型项_Ptr为访问所有项;
包装项目_Vectors是新的Ada.Containers.Vectors
(索引类型=>自然,
元素类型=>项目类型
);
子类型向量为Item_Vectors.Vector;
类型Vector_Ptr是访问所有向量;
类型项(IType:type\U T:=T\U Null)为记录
案例类型为
当T_Null=>Null时;
当T_Unsigned_64=>Value_Unsigned_64时:Unsigned_64;
当T_String=>Value_String:String_Ptr;
当T_Boolean=>Value_Boolean时:Boolean;
当T_Vector=>Value_Vector:Vector_Ptr;
终例;
结束记录;
(我删除了绿色任务,希望与您的问题无关)
我很感兴趣地看到,如果不完整的声明是在私有部分,那么完整的声明只能推迟到正文中。我对此进行了研究,发现我可以通过制作元素类型Item\u Ptr
的Item\u Vectors
来编译它:
type Item (<>);
type Item_Ptr is access all Item;
package Item_Vectors is new Ada.Containers.Vectors
( Index_Type => Natural,
Element_Type => Item_Ptr
);
subtype Vector is Item_Vectors.Vector;
type Vector_Ptr is access all Vector;
type Item (IType : Type_T := T_Null) is record
case IType is
when T_Null => null;
when T_Unsigned_64 => Value_Unsigned_64 : Unsigned_64;
when T_String => Value_String : String_Ptr;
when T_Boolean => Value_Boolean : Boolean;
when T_Vector => Value_Vector : Vector_Ptr;
end case;
end record;
类型项();
类型项_Ptr为访问所有项;
包装项目_Vectors是新的Ada.Containers.Vectors
(索引类型=>自然,
元素类型=>项目类型
);
子类型向量为Item_Vectors.Vector;
类型Vector_Ptr是访问所有向量;
类型项(IType:type\U T:=T\U Null)为记录
案例类型为
当T_Null=>Null时;
当T_Unsigned_64=>Value_Unsigned_64时:Unsigned_64;
当T_String=>Value_String:String_Ptr;
当T_Boolean=>Value_Boolean时:Boolean;
当T_Vector=>Value_Vector:Vector_Ptr;
终例;
结束记录;
(我删除了绿色任务,希望与您的问题无关)
我很感兴趣地从中看到,如果不完整的声明在私有部分,则完整的声明只能推迟到正文中。好的,我假设您在实例化项向量
并说使用项向量
时,Vector
输入Item\u Vectors
将完成前面编写的不完整的Vector
没有。当您说use P
时,这意味着P
中定义的所有名称现在都可以直接看到,因此如果P
声明类型T
,您可以说T
,而不是说P.T
但符号仍然属于P。它们不会成为包含use
的包的“一部分”。因此,例如,使用项_向量
表示您可以说空光标
,而不是项向量。空光标
。但是将有而不是一个Types.Boxed.Empty\u光标
。该名称仍然属于项向量
这意味着当您在类型中有一个不完整的向量类型时,需要在类型中有一个完成。Item\u Vectors
中的Vector
类型不会成为该类型的补全,而使用
也没有帮助
不幸的是,Ada不允许您使用“类型重命名”或子类型来完成类型。我能想到的最好的选择是
type Vector is new Item_Vectors.Vector with null record;
请注意,这会导致项_Vector
中的所有操作被继承到Vector
。所以这可能对你有用。但可能会有一些意想不到的问题。但我想不出更好的解决办法
编辑:Simon似乎有一个很好的解决方案。好吧,我假设您在实例化项目向量
并说使用项目向量
时认为,向量
输入项目向量
将是您之前编写的不完整向量
的完成
没有。当您说use P
时,这意味着P
中定义的所有名称现在都可以直接看到,因此如果P
声明类型T
,您可以说T
,而不是说P.T
但符号仍然属于P。它们不会成为包含use
的包的“一部分”。因此,例如,使用项_向量
表示您可以说空光标
,而不是项向量。空光标
。但是将有而不是一个Types.Boxed.Empty\u光标
。该名称仍然属于项向量
这意味着当您在类型中有一个不完整的向量类型时,需要在类型中有一个完成。Item\u Vectors
中的Vector
类型不会成为该类型的补全,而使用
也没有帮助
不幸的是,Ada不允许您使用“类型重命名”或子类型来完成类型。我能想到的最好的选择是
type Vector is new Item_Vectors.Vector with null record;
请注意,这会导致Item_Vector
中的所有操作为继承