gpt4 book ai didi

generics - 泛型参数丢失信息

转载 作者:行者123 更新时间:2023-12-02 08:03:46 25 4
gpt4 key购买 nike

泛型参数的声明不够详尽,无法给出类型关系(子类型),并且此信息会丢失......例如:

-- generic_p.ads
generic
type Index_Range_Type is range <>;
type Count_Range_Type is range <>;
procedure Generic_P (I : Index_Range_Type, C : Count_Range_Type);

-- generic_p.adb
procedure Generic_P (I : Index_Range_Type, C : Count_Range_Type) is
begin
if I = C then -- oops : cannot compare different types...
-- ...
end if;
end Generic_P;

-- main.adb
procedure Main is
type Index_Range_Type is 0 .. 512;
subtype Count_Range_Type is Index_Range_Type range 1 .. Index_Range_Type'Last;

procedure P is new Generic_P (Index_Range_Type, Count_Range_Type);

I : Index_Range_Type := 33;
C : Count_Range_Type := 42;
begin
if I = C then -- Ok : Count_Range is a subset of Index_Range, they can be compared
-- ...
end if;
P (I, C);
end Main;

在 generic_p.adb 中进行比较时会出现以下错误:操作数类型无效 [...] 左操作数的类型为“Index_Range_Type”[...] 右操作数的类型为“Count_Range_Type” 。子类型在通用过程中不可见。

有没有办法指定泛型参数之间的关系?

更多信息

我确实需要 Count_Range_Type 作为过程的参数,以便能够添加另一个需要 Count_Range_Type 的参数。

-- generic_p.ads
generic
type Index_Range_Type is range <>;
type Count_Range_Type is range <>;
with procedure F (C : Count_Range_Type);
procedure Generic_P (I : Index_Range_Type, C : Count_Range_Type);

我不能直接使用类型,我需要 P 是绝对通用且独立的。

最佳答案

这解决了原始问题的“更多信息”部分,即需要使用包含作为实例化类型的子类型的参数的过程来实例化泛型。

本质上,使用通用包来设置子类型,然后通用子包提供所需的过程(用通用正式过程实例化)。诚然,这是一个相当复杂的问题解决方案。那么我们开始吧:

创建子类型的“父”泛型:

generic
type Index_Range_Type is range <>;
package Generic_Provider is
pragma Assert(Index_Range_Type'First = 0);
subtype Count_Range_Type is Index_Range_Type range 1 .. Index_Range_Type'last;

end Generic_Provider;

这只是声明子类型,它不需要主体(事实上主体是非法的)。

这是我们的程序提供商的规范,它使用客户提供的正式程序。

generic
with procedure F(I : Index_Range_Type;
C : Count_Range_Type);

package Generic_Provider.Services is

procedure P (I : Index_Range_Type; C : Count_Range_Type);

end Generic_Provider.Services;

只是为了咧嘴一笑,它的主体,验证可以调用正式过程并且子类型比较有效:

package body Generic_Provider.Services is

procedure P (I : Index_Range_Type; C : Count_Range_Type) is
begin
if I = C then
F(I, C);
end if;
end P;

end Generic_Provider.Services;

最后实例化主程序:

with Generic_Provider.Services;

procedure Main is
type Index_Range_Type is range 0 .. 512;
package Type_Provider is new Generic_Provider (Index_Range_Type);
subtype Count_Range_Type is Type_Provider.Count_Range_Type;

procedure My_F (I : Index_Range_Type;
C : Count_Range_Type) is
begin
null;
end My_F;

package P_Provider is new Type_Provider.Services(My_F);

I : Index_Range_Type := 33;
C : Count_Range_Type := 42;
begin
if I = C then
null;
end if;
P_Provider.P (I, C);
end Main;

关于generics - 泛型参数丢失信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11331374/

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