gpt4 book ai didi

generics - 在 Ada 中,为什么不使用泛型父级实例化子级,为什么我也必须使其成为泛型?

转载 作者:行者123 更新时间:2023-12-03 21:07:54 26 4
gpt4 key购买 nike

我有一个带有一些通用接口(interface)的父包。我现在想创建这个接口(interface)的几个实现,每个都在不同的文件中。我以为我可以简单地将这些包作为包含接口(interface)的包的子包,实例化泛型,然后直接访问子包,但这给了我一个错误,即子包也必须是泛型的。
这导致我进行以下实现:
父广告:

generic
type T is private;

package Parent is

type I_Generic is interface;
type Any_Generic is access all I_Generic'Class;

function Get (This : in out I_Generic) return T is abstract;
procedure Set (This : in out I_Generic; Value : T) is abstract;

end Parent;
父子广告:
generic
package Parent.Child is

-- long spec

type Impl is new I_Generic with private;
type Impl_Access is access all Impl;

overriding function Get (This : in out Impl) return T;
overriding procedure Set (This : in out Impl; Value : T);

private

type Impl is new I_Generic with
record
Data : T;
end record;

end Parent.Child;
父子.adb:
package body Parent.Child is

-- long body

overriding
function Get (This : in out Impl) return T is
begin
return This.Data;
end Get;

overriding
procedure Set (This : in out Impl; Value : T) is
begin
This.Data := Value;
end Set;

end Parent.Child;
tester.adb:
with Ada.Text_IO;
with Parent;
with Parent.Child;

package body Tester is

package Parent_Inst is new Parent (T => Integer);
package Child_Inst is new Parent_Inst.Child;

procedure Test is
Instance : constant Child_Inst.Impl_Access := new Child_Inst.Impl;
Polymorphic : constant Parent_Inst.Any_Generic := Parent_Inst.Any_Generic (Instance);
begin
Instance.Set (42);
Ada.Text_IO.Put_Line (Polymorphic.Get'Img);
end Test;

end Tester;
结果:
42
为什么我需要使子包通用,然后先创建它的实例?为什么我不能简单地使用 Instance : Parent_Inst.Child.Impl_Access := new Parent_Inst.Child.Impl; ?
有什么办法可以让我更清洁吗?也许我忽略了一个不同的解决方案来满足我的要求,它更简单并且没有这个问题?或者这只是实现我所描述的方法,我应该接受额外包实例化的冗长吗?在我自己的代码中,我现在必须为每个接口(interface)实现包创建几个包实例化,这会导致许多额外的代码行。

最佳答案

由于LRM 10.1.1, 17/3,子包必须是通用的:

A child of a generic library package shall either be itself a generic unit or be a renaming of some other child of the same generic unit.


这是必要的,因为子包可以访问父单元的通用参数的值,除非父单元被实例化,否则该参数不存在。
现在在 Ada 中,泛型实例化是显式的,并且每个实例化恰好实例化一个泛型单元。在你的情况下,
package Parent_Inst is new Parent (T => Integer);
实例化 Parent包裹。它不实例化 Parent.Child因为那是一个单独的通用单元。因此,您确实需要实例化 Child分别地。
您可以编写一个一次性实例化所有的帮助程序包,例如
generic
type T is private;
package Everything is
package Parent_Inst is new Parent (T);
package Child_Inst is new Parent_Inst.Child;
end Everything;
然后实例化 Everything您需要实例的地方。

关于generics - 在 Ada 中,为什么不使用泛型父级实例化子级,为什么我也必须使其成为泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65572076/

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