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
根据 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