在"盒装类型"的实现中(对于解释器)我最初在子包中有向量,并使用System.Access_To_Address_Conversions根据需要从System.Address转换为Vector_Ptr,以避免看似无法克服的循环依赖性问题。 (至少,没有使用限制,每一个对我来说都是伎俩。)它工作但似乎是一个讨厌的黑客。所以我决定将容器类型放入主包Types.Boxed中。现在,GNAT抱怨'在不完整类型的可见部分中没有声明" Vector"在第12行'
中定义有什么方法可以解决这个问题吗?或者我应该回到我讨厌的黑客?
Ada 2005使用GNAT 4.6与标志-gnat05
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;
答案 0 :(得分:3)
好的,我假设您在实例化Item_Vectors
并说use Item_Vectors
时认为Vector
中的Item_Vectors
类型将是不完整{{1}的完成你之前写的。
没有。当您说Vector
时,表示use P
中定义的所有名称现在都可以直接显示,因此如果P
声明类型为P
,则可以说T
而不是说T
。 但符号仍然属于P。它们不会成为包含P.T
的包的“一部分”。因此,例如,use
表示您可以说use Item_Vectors;
而不是Empty_Cursor
。但是不是Item_Vectors.Empty_Cursor
。该名称仍属于Types.Boxed.Empty_Cursor
。
这意味着当Item_Vectors
中的Vector
类型不完整时,需要在 Types.Boxed
中完成。 Types.Boxed
中的Vector
类型无法完成此类型,Item_Vectors
对此无效。
不幸的是,Ada不允许您使用“类型重命名”或use
来完成类型。我能想到的最佳选择是
subtype
请注意,这会导致type Vector is new Item_Vectors.Vector with null record;
继承Item_Vector
中的所有操作。所以这可能适合你。但可能会出现一些意想不到的问题。但我想不出更好的解决方案。
编辑:看起来西蒙有一个很好的解决方案。
答案 1 :(得分:1)
我玩弄了这个,发现我可以通过制作元素类型Item_Vectors
的{{1}}来进行编译:
Item_Ptr
(我删除了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;
,希望与您的问题无关。)
我有兴趣从ARM 3.10.1(3)看到,如果不完整的声明属于私人部分,则完整声明只能推迟到正文。