2014-04-08 98 views
0

在「盒裝類型」的實施方案(用於解釋器)我本來在子包載體中並用作System.Access_To_Address_Conversions從System.Address轉換爲Vector_Ptr如需要的,以便避免循環依賴看似不可逾越的問題。 (至少,每個人都沒有使用限制我的技巧。)它的工作,但似乎是一個討厭的黑客。所以我決定把容器類型放入Types.Boxed主包中。現在GNAT抱怨互相依賴類型聲明和Ada.Containers

有什麼辦法來解決這個問題「在第12行中定義的類型不完全‘矢量’可見部分沒有聲明」?或者我應該回到我討厭的黑客手中?

阿達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; 

回答

3

OK,我假設你想,當你實例化Item_Vectorsuse Item_Vectors,該Vector類型Item_Vectors將是不完整的Vector您之前寫的完成。

它沒有。當您說use P時,這意味着現在可以直接看到P中定義的所有名稱,因此如果P聲明瞭T類型,則可以說T而不是P.T但符號仍然屬於P.它們不會成爲包含use的包的一部分。因此,例如,use Item_Vectors;意味着您可以說Empty_Cursor而不是Item_Vectors.Empty_Cursor。但是會有而不是Types.Boxed.Empty_Cursor。該名字仍然屬於Item_Vectors

這意味着,當你在Types.Boxed不完整Vector類型,需要有一個完成Types.Boxed。在Item_Vectors中的Vector類型不成爲該類型的完成,並且use對此沒有幫助。

不幸的是,艾達不會讓你有「型重命名」或subtype完成的類型。我能想到的最好的辦法是

type Vector is new Item_Vectors.Vector with null record; 

注意,這導致Item_Vector所有的操作繼承了Vector。所以這可能適合你。但可能會有一些意想不到的問題。但我想不出一個更好的解決方案。

編輯:它看起來像西蒙擁有良好的解決方案。

+0

擴展任何Container的問題是返回容器類型(Vector有7個值)並因此必須被覆蓋的函數的數量。 –

+1

@SimonWright不,從Ada 2005開始,函數不必在類型擴展是_null擴展_時被覆蓋。 – ajb

+0

O是的,我現在記得,* my *在這些行上的嘗試是爲了擴展有額外的內容。哎呀。 –

1

我這個玩了一圈,發現我可以得到它通過使元素類型Item_PtrItem_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; 

(我刪除了Green_Tasks,希望與您的問題無關)。

我很感興趣,從ARM 3.10.1(3)看,如果不完整的申報是在私處的完整的聲明只能被推遲到身體。