Ada 2012 中正式不完整类型的规则

Rules for formal incomplete types in Ada 2012

根据 AI05-213,泛型现在可以用不完整的类型实例化。我想用它来构建不透明的容器:几个包定义了私有类型和匹配的容器。但是,我希望容器派生自一个通用的 Containers.Container 类型,该类型将提供一些简单的子程序(例如 Clear、Is_Empty、Iterate)。对于后者,需要容器中存储元素的类型,所以package Containers必须是泛型的。

我无法编译我的代码,所以我做了一些试验。看来我可以使用标记类型,但不能使用 class 范围的类型,也不能使用标记类型的子类型。

为什么会这样?知道如何实现与私有元素和各种具体容器(例如 Map、Linked List、Set)一起工作的简单容器抽象吗?

用于测试的代码:

actual.ads

with Containers;

package Actual is
   type Element is tagged private;
   type Sub_Element is new Element with private;
   package List is new Containers (Element_Type => Element'class); --error
   package Another is new Containers (Element_Type => Element); --ok
   package Still_Another is new Containers (Element_Type => Sub_Element); --error
private
   type Element is tagged null record;
   type Sub_Element is new Element with null record;
end Actual;

containers.ads

generic
   type Element_Type (<>) is tagged;
package Containers is
   type Container is abstract tagged null record;
end Containers;

Element 类型移动到另一个包会改变整个问题,因为这样就不再存在过早使用私有组件类型的问题。可能是编译错误(目前的Pro版本还是显示这两个错误),但我不太确定。

不过,我认为在实践中,像您这样使用不完整的类型不太可能很有用。对于容器包中的 Element_Type 基本上你无能为力,因为除了它被标记之外你对它一无所知。您不能存储这样的元素(不确定)。

使用动态调度对性能也很不利。我最近花了很多时间测量东西,我建议你在设计的早期也这样做。您会看到动态调度的成本非常高。我自己的经验是,最好为该方法使用泛型。如果允许我无耻地插入,如果您正在设计容器,您可能会发现最近的一篇博客 post 很有趣:http://blog.adacore.com/traits-based-containers