我可以使用两者都填充矢量,类型A和B吗?我将只用一种类型填充它,所以我总是确定,我会从中得到什么。但如果我可以定义一次矢量,那么对我来说很容易做很多事情。
type T is tagged null record;
type A is new T with
record
x : Integer;
end record;
type B is new T with
record
y : Integer;
end record;
package Some_Vector is new Ada.Containers.Indefinite_Vectors (
Index_Type => Positive,
Element_Type => T <- ???
);
答案 0 :(得分:2)
你可以说:
package Some_Vector is new Ada.Containers.Indefinite_Vectors (
Index_Type => Positive,
Element_Type => T'Class
);
Some_Vector
现在可以保存T
类型的元素或从中派生的任何类型,包括A
或B
。并不要求所有元素必须属于同一类型,只要它们都来自T
;所以如果你真的不关心这个属性是否被强制执行,那么上面应该可行。如果你真的希望编译器强制所有元素都是相同的类型,那么你应该简单地为两种类型的向量声明两个包A_Vector
和B_Vector
;但是那时候没有办法写一个&#34;全班级的&#34;类型名称,可以引用A_Vector
或B_Vector
。
如果你真的想要两者结合 - 有一个矢量类型可以引用A
的向量或B
的向量,但仍然强制向量的所有元素都有相同类型,那么我认为如果您定义自己的矢量类型并在运行时执行所需的检查,这可以完成,但它可能会变得复杂。编译,但我还没有测试过它:
generic
type Elem is new T with private;
package Sub_Vectors is
type Sub_Vector is new Some_Vector.Vector with null record;
overriding
procedure Insert (Container : in out Sub_Vector;
Before : in Some_Vector.Extended_Index;
New_Item : in T'Class;
Count : in Ada.Containers.Count_Type := 1)
with Pre => New_Item in Elem;
end Sub_Vectors;
package body Sub_Vectors is
procedure Insert (Container : in out Sub_Vector;
Before : in Some_Vector.Extended_Index;
New_Item : in T'Class;
Count : in Ada.Containers.Count_Type := 1) is
begin
Some_Vector.Insert
(Some_Vector.Vector(Container), Before, New_Item, Count);
end Insert;
end Sub_Vectors;
不幸的是,您必须覆盖可能将元素放入向量的每个Insert
和Replace_Element
操作。但是,完成所有这些操作后,您可以使用Sub_Vectors
和Elem => A
实例化Elem => B
,而类Some_Vector.Vector'Class
将是包含两个{的类范围类型{1}}实例包中的类型。
答案 1 :(得分:0)
如果你真的希望编译器强制所有元素都是 相同的类型,那么你应该简单地声明两个包,
A_Vector
和B_Vector
,适用于两种类型的向量;但那时就没办法了 写一个“类范围”类型名称,可以引用A_Vector
或B_Vector
。
但是,您可以使用仅指向层次结构的A或B子树的向量:
type T is tagged null record;
type A is new T with null record;
type B is new T with null record;
type C is new T with null record;
type TAB is access all T'Class
with Dynamic_Predicate =>
TAB = null or else
(TAB.all in A'Class or TAB.all in B'Class);
上面产生TAB
类型,它必须是[指向] A'Class或B'Class的指针,你应该可以在你的向量中使用它。 - 我遇到的唯一问题是你必须使用GNAT的'Unchecked_Access来获取对象的访问值(我认为,应该是我的快速和肮脏的测试)。