Vector 带标记类型的向量

Vector 带标记类型的向量,vector,ada,Vector,Ada,我可以用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_Ve

我可以用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 <- ???
);
类型T被标记为空记录;
A型是新的T型
记录
x:整数;
结束记录;
B型是新的T型
记录
y:整数;
结束记录;
包中的一些_向量是新的Ada.Containers.unfinite_向量(
索引类型=>正,
元素类型=>T你可以说:

package Some_Vector is new Ada.Containers.Indefinite_Vectors (
   Index_Type => Positive,
   Element_Type => T'Class
);
Some_Vector
现在可以保存类型为
T
的元素或从中派生的任何类型的元素,包括
A
B
。不要求所有元素都必须是同一类型的,只要它们都是从
T
派生的;因此,如果您并不真正关心是否强制执行此属性,则above应该可以工作。如果您真的希望编译器强制所有元素都是相同的类型,那么您只需为这两种类型的向量声明两个包,
A_Vector
B_Vector
;但这样就无法编写“类范围”的键入可以引用
A_向量
B_向量
的名称

如果你真的想把两者结合起来——有一个向量类型,它可以引用
a
的向量或
B
的向量,但仍然要求向量的所有元素都具有相同的类型,那么我认为如果你定义自己的向量类型并在运行时执行所需的检查,这是可以做到的,但它可能会变得复杂d、 这可以编译,但我还没有测试它:

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\u-Element
操作,这些操作可能会将元素放入向量中。但是,在完成所有这些操作之后,您可以使用
Elem=>A
Elem=>B
实例化
子向量
,而类
将使用一些向量是一个类范围的类型,将在实例包中同时包含
子_Vector
类型

如果您确实希望编译器强制所有元素都是 相同类型,那么您只需声明两个包,
A_Vector
B_Vector
,用于两种类型的向量;但是没有办法 写一个“类范围”类型名,可以引用
a\u向量
或者a
B_向量

但是,可以有一个仅指向层次结构的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);

上面给出了
选项卡
类型,它必须是一个指向a'类或B'类的指针,您应该能够在向量中使用它。--我遇到的唯一问题是您必须使用GNAT的“未检查的”访问来获取对象的访问值(我想,这是由于我的快速而肮脏的测试).

您发布的代码不应该要求
取消选中_Access
;这方面的需要更多的是关于别名变量在什么范围内声明,而不应该与类型的声明方式有任何关系。当然,这是假设没有GNAT BUG。。。(P.S.
未经检查的访问
是由语言定义的。它不是一个GNAT特殊。)是吗?我认为它就像是
'Img
。是的,在RM 13.10(3)中定义。你可能会想到
无限制的访问
,这不是由语言定义的。该属性可能会给你更多的空间来违反类型规则,但我不确定。