相互依赖的类型声明和Ada.Containers

时间:2014-04-08 18:14:29

标签: ada recursive-datastructures

在"盒装类型"的实现中(对于解释器)我最初在子包中有向量,并使用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;

2 个答案:

答案 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)看到,如果不完整的声明属于私人部分,则完整声明只能推迟到正文。