簡體   English   中英

Ada通用包擴展

[英]Ada Generic Package Extension

我有一個通用包Containers.Stacks看起來大致相似

generic
    type Value_Type is private;
package Containers.Stacks with Preelaborate is

    --Node stuff

    type Stack is new Container with private;

    --Other Stack stuff
    --Private stuff
end Containers.Stacks;

一切都是(似乎)工作得很好。 我想重用此實現來創建擴展但更窄的目的堆棧。 我想出了以下內容:

with Containers.Stacks;

generic
    type Value_Type is range <>;
package Containers.Integer_Stacks with Preelaborate is

    package Stacks is new Containers.Stacks(Value_Type);
    use Stacks;

    type Stack is new Stacks.Stack with null record;

    procedure Add(Self : in out Stack);

    procedure Subtract(Self : in out Stack);

    --So on

end Containers.Integer_Stacks;

關鍵是,我不想重新實現所有常見的Stack內容,只針對特定的整數堆棧。 這可行,但留下了一個丑陋而奇怪的Containers.Integer_Stacks.StackContainers.Integer_Stacks.Stacks.Stack混亂,我想避免。 但是,嘗試將包初始化放在私有部分中也會隱藏所有子例程。 有沒有更合適的方法來完成我想要做的事情,或者用戶是否必須處理存在的兄弟包初始化?

替代方法:我發現可以定義一個名為Containers.Stacks.IntegerContainers.Stacks子包,如下所示:

generic
    with function "+"(Left, Right: Value_type) return Value_Type is <>;
package Containers.Stacks.Integer is
    procedure Add(Self : in out Stack);
end Containers.Stacks.Integer;

這很有效。 除了現在我不能調用Stack.Add ,我被迫調用Add(Stack)

你可以看看

with Containers.Stacks;
generic
   type Value_Type is range <>;
   with package Basis_Stack is new Containers.Stacks (Value_Type => Value_Type);
package Containers.Integer_Stacks with Preelaborate is
   type Stack is new Basis_Stack.Stack with private;
...

這確實需要您的用戶自己適當地實例化Container.Stacks。

您對解決方案的想法並不是為您提供更窄的類型,而是為您提供更多操作。

如果你想要一個更窄的類型,你碰巧在內部使用現有的類型,你可以像這樣(未經測試的源):

private with Containers_Stack;

generic
   type Value_Type is range <>;
package Containers.Integer_Stack
  with Preelaborate
is
   type Instance is tagged private with null record;

   procedure Add (Item : in out Instance);
   procedure Subtract (Item : in out Instance);
private
   package Internal_Stack is new Containers.Stacks (Value_Type);

   type Instance is tagged private with
      record;
         Data : Internal_Stack.Stack;
      end record;
end Containers.Integer_Stack;

這樣, Containers.Integer_Stack客戶端只能使用您在包規范中明確列出的操作。

其他提出的答案由於各種原因而很好,但我認為在兄弟中自動公開基本容器類型的子例程太重要了。 因此,最好的答案是我最初的實施。 希望其他開發人員會發現其他答案很有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM