根据AI05-213 ,泛型现在可以用不完整的类型进行实例化。我想用它来构建不透明容器:几个包定义私有(private)类型和匹配容器。但是,我希望容器派生自通用 Containers.Container 类型,该类型将提供一些简单的子程序(例如 Clear、Is_Empty、Iterate)。对于后者,需要在容器中存储元素的类型,因此包 Containers 必须是通用的。
我无法编译我的代码,所以我进行了一些尝试。看来我可以使用标记类型,但不能使用类范围类型,也不能使用标记类型的子类型。
为什么会这样呢?知道如何实现一个与私有(private)元素和各种具体容器(例如映射、链接列表、集合)一起使用的简单容器抽象吗?
用于测试的代码:
实际.广告
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;
容器.广告
generic
type Element_Type (<>) is tagged;
package Containers is
type Container is abstract tagged null record;
end Containers;
最佳答案
将 Element
类型移动到另一个包会改变整个问题,因为这样就不再存在过早使用私有(private)组件类型的问题。这可能是一个编译器错误(当前的专业版仍然显示这两个错误),但我不太确定。
但在实践中,我认为像您这样使用不完整类型不太可能很有用。对于容器包中的 Element_Type
基本上您无能为力,因为除了它被标记之外您对它一无所知。您无法存储这样的元素(这是不确定的)。
使用动态调度对于性能来说也很糟糕。我最近花了很多时间来测量事物,我建议您在设计的早期就这样做。你会发现动态调度的成本是相当昂贵的。我自己的经验是,最好使用泛型来实现这种方法。如果我可以被允许无耻地插入,如果您正在设计容器,您可能会发现最近的一篇博客文章很有趣:http://blog.adacore.com/traits-based-containers
关于generics - Ada 2012 中正式不完整类型的规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33496741/