矢量与标记类型

时间:2014-02-21 20:51:10

标签: 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_Vector is new Ada.Containers.Indefinite_Vectors (
   Index_Type => Positive,
   Element_Type => T <- ???
);

2 个答案:

答案 0 :(得分:2)

你可以说:

package Some_Vector is new Ada.Containers.Indefinite_Vectors (
   Index_Type => Positive,
   Element_Type => T'Class
);

Some_Vector现在可以保存T类型的元素或从中派生的任何类型,包括AB。并不要求所有元素必须属于同一类型,只要它们都来自T;所以如果你真的不关心这个属性是否被强制执行,那么上面应该可行。如果你真的希望编译器强制所有元素都是相同的类型,那么你应该简单地为两种类型的向量声明两个包A_VectorB_Vector;但是那时候没有办法写一个&#34;全班级的&#34;类型名称,可以引用A_VectorB_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;

不幸的是,您必须覆盖可能将元素放入向量的每个InsertReplace_Element操作。但是,完成所有这些操作后,您可以使用Sub_VectorsElem => 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来获取对象的访问值(我认为,应该是我的快速和肮脏的测试)。