gpt4 book ai didi

generics - 包含对基于该记录的通用包实例化的访问的记录

转载 作者:行者123 更新时间:2023-12-04 04:56:57 27 4
gpt4 key购买 nike

这真的是一个很烦人的问题。我有一个包含各种基本类型的记录类型,现在我需要它来存储一个向量(来自 Ada.Containers.Vectors)!我想这是不可能的,但有人可以就如何以另一种方式解决这个问题给我建议吗?为了让您更好地了解我在做什么,以下是行不通的:

with Base_Types; use Base_Types;
with Ada.Strings.Wide_Unbounded; use Ada.Strings.Wide_Unbounded;
with Ada.Containers.Vectors;
with Green_Tasks; use Green_Tasks;
with Ada.Unchecked_Deallocation;

package Boxed_Types is

type String_Ptr is access Unbounded_Wide_String;
procedure Free_Unbounded_Wide_String is new Ada.Unchecked_Deallocation
(Object => Unbounded_Wide_String, Name => String_Ptr);
type Vector_Ptr; -- this won't work

type Type_T is (T_Null, T_UInt64, T_Text, T_Bool, T_GTask, T_Vector);
type Item (IType : Type_T := T_Null) is record
case IType is
when T_Null => null;
when T_UInt64 => UInt64 : UInteger_64;
when T_Text => String : String_Ptr;
when T_Bool => Bool : Boolean;
when T_GTask => Green_Task : Green_Task_Ptr;
when T_Vector => Item_Vector : Vector_Ptr; -- error here
end case;
end record;

package Item_Vectors is new Ada.Containers.Vectors
(Index_Type => Natural,
Element_Type => Item);
use Item_Vectors;
type Vector_Ptr is access Vector;
end Boxed_Types;

这给了我一个不太意外的错误“在完全声明之前无效使用类型”对于 Vector_Ptr。但是,在声明 Item 之前,我也无法实例化 vector 包,而且我确实需要将 vector 和基本类型包装到一种记录类型中。 (这是我在业余时间写的解释器;VM 必须在堆栈上存储各种不同的类型,在异构数组中,操作它们等。)

我是否必须完全打破类型安全并乱用地址来访问转换,还是有更干净的解决方案?

最佳答案

这是一个不同的版本,它在 Vector 中存储了 Item(而不是它的访问权限)。它通过使用继承来工作,创建一个基本类型的 Vector。这意味着一个 Indetermine_Vector,因为每个单独组件的大小是事先未知的。

再次编译但未经测试。

with Ada.Containers.Indefinite_Vectors;

package Boxed_Base is

type Base_Item is tagged record
null;
end record;

package Item_Vectors is new Ada.Containers.Indefinite_Vectors
(Index_Type => Natural,
Element_Type => Base_Item'Class);
use Item_Vectors;

type Vector_Ptr is access Vector;

end Boxed_Base;

该基类型具有可以存储在向量中的特性,并且其存储管理由 Indetermine_Vectors 处理。现在我们可以继承它,具有我们需要的特性。
with Ada.Strings.Wide_Unbounded; use Ada.Strings.Wide_Unbounded;
with Ada.Unchecked_Deallocation;
with Boxed_Base;

package Boxed_Types is

type UInteger_64 is new integer;
type Green_Task_Ptr is access UInteger_64;
-- these two because original testcase was incomplete

type String_Ptr is access Unbounded_Wide_String;
type Type_T is (T_Null, T_UInt64, T_Text, T_Bool, T_GTask, T_Vector);

type Item (IType : Type_T ) is new Boxed_Base.Base_Item with record
case IType is
when T_Null => null;
when T_UInt64 => UInt64 : UInteger_64;
when T_Text => String : String_Ptr;
when T_Bool => Bool : Boolean;
when T_GTask => Green_Task : Green_Task_Ptr;
when T_Vector => Item_Vector : Boxed_Base.Vector_Ptr;
end case;
end record;

end Boxed_Types;

原始设计的一个特征已经消失:默认判别式不允许用于标记类型:这意味着您创建一个具有明确判别式(因此具有确定大小!)的实例并且以后无法修改它(只需将对象替换为新的)。

另一个特性可能值得一提: Indetermine_Vectors 可能比它们的 Definite 表亲有性能损失:如果是这样,那是异构对象大小产生的必要成本,并且会以某种形式弹出,无论您如何解决问题。

也可以通过为每种类型的 Item 创建不同的子类来消除判别式 Type_T;也许是一个更简洁的设计,但在这个阶段,它比你想要的更重构!

关于generics - 包含对基于该记录的通用包实例化的访问的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16638137/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com