Generics 如何使用子包/泛型包实例化中的类型
我可以使用Generics 如何使用子包/泛型包实例化中的类型,generics,ada,Generics,Ada,我可以使用 像这样使用所有类型: package Type_Package is type T is null record; procedure Action(X: T) is null; end Type_Package; with Type_Package; procedure Use_Type is use all type Type_Package.T; X: Type_Package.T; begin Action(X); end Use_Type;
像这样使用所有类型
:
package Type_Package is
type T is null record;
procedure Action(X: T) is null;
end Type_Package;
with Type_Package;
procedure Use_Type is
use all type Type_Package.T;
X: Type_Package.T;
begin
Action(X);
end Use_Type;
1. procedure B840003 is
2. begin
3.
4. declare
5. package Pkg_1 is
6. type Enum is (Aaa, Bbb, Ccc);
7. procedure Prim_Proc (X : Enum := Aaa) is null;
8. function Prim_Func return Enum is (Bbb);
9.
10. package Nested is
11. procedure Nonprim_Proc (X : Enum := Bbb) is null;
12. function Nonprim_Func return Enum is (Ccc);
13. end Nested;
14.
15. end Pkg_1;
16.
17. begin
18. declare
19. use all type Pkg_1.Enum;
20. begin
21. if Prim_Func /= Bbb then -- OK.
22. null;
23. end if;
24. if Nonprim_Func (Ccc) /= Ccc then -- ERROR:
|
>>> "Nonprim_Func" is not visible
>>> non-visible declaration at line 12
25. null;
26. end if;
27. Prim_Proc; -- OK.
28. Nonprim_Proc (Aaa); -- ERROR:
|
>>> "Nonprim_Proc" is not visible
>>> non-visible declaration at line 11
29. end;
30. end;
31.
32. end B840003;
但是,当我将Type_Package
移到内部时,它似乎不起作用
使用类型
procedure Use_Type is
package Type_Package is
type T is null record;
procedure Action(X: T) is null;
end Type_Package;
use all type Type_Package.T;
X: Type_Package.T;
begin
Action(X);
end Use_Type;
我明白了
当我实例化一个泛型包时,也会发生同样的事情。对于
例如,当我想使用Ada.Containers
中的数据类型时
package Element_Set is
new Ada.Containers.Hashed_Sets(Element_Type, Hash, "=");
use all type Element_Set.Set;
这里的use type
子句似乎没有效果
在子包或子包中声明类型时如何使用该类型
通用包的实例化?我不确定这是编译器错误(更新:Simon Wright确认它是错误)还是有意的,但您的解决方案包括:
对整个软件包使用“Use Type_Package”——可能是最简单但最繁重的一种
使用一些过程/函数重命名子句-这需要更多的工作,但不会使整个包可见。例如:
过程Hello是
包类型\u包为
类型T为空记录;
程序动作(X:T)为空;
端型包装;
使用所有类型的包装;
X:Type_Package.T;
程序操作(X:Type_Package.T)重命名Type_Package.Action;
开始
行动(X);
结束问候;
对于泛型包,在库级别声明它们-这对嵌套包没有帮助,但对泛型包有帮助。您可以对单个泛型包执行以下操作:
类型_Package.ads
使用所有类型;
包装类型\包装是新使用的\所有\类型;
使用所有类型的广告
通用
包使用所有类型为
类型T为空记录;
程序动作(X:T)为空;
所有类型的最终用途;
或对于多个通用软件包:
类型_Package.ads
使用所有类型;
包类型\u包为
机组UAT为新用途全自动型;
T亚型为UAT.T;
使用所有类型的UAT.T;
--对其他泛型重复上述步骤
端型包装;
使用所有类型的广告
通用
包使用所有类型为
类型T为空记录;
程序动作(X:T)为空;
所有类型的最终用途;
这两种方法都适用于以下主要方面:
带有类型_包;
主要程序是
使用所有类型的包装;
X:Type_Package.T;
开始
行动(X);
端干管;
旁注:如果在这里没有人明确回答这是不是有意的,你可以考虑发送AdACOR错误报告。
< p>你确实发现了编译器错误。 有一组测试(ACAT-也是),其中“B系列”设计用于检查编译器是否捕获错误 其中一个测试从您的问题开始:一个精简和稍微修改的版本的行为如下:package Type_Package is
type T is null record;
procedure Action(X: T) is null;
end Type_Package;
with Type_Package;
procedure Use_Type is
use all type Type_Package.T;
X: Type_Package.T;
begin
Action(X);
end Use_Type;
1. procedure B840003 is
2. begin
3.
4. declare
5. package Pkg_1 is
6. type Enum is (Aaa, Bbb, Ccc);
7. procedure Prim_Proc (X : Enum := Aaa) is null;
8. function Prim_Func return Enum is (Bbb);
9.
10. package Nested is
11. procedure Nonprim_Proc (X : Enum := Bbb) is null;
12. function Nonprim_Func return Enum is (Ccc);
13. end Nested;
14.
15. end Pkg_1;
16.
17. begin
18. declare
19. use all type Pkg_1.Enum;
20. begin
21. if Prim_Func /= Bbb then -- OK.
22. null;
23. end if;
24. if Nonprim_Func (Ccc) /= Ccc then -- ERROR:
|
>>> "Nonprim_Func" is not visible
>>> non-visible declaration at line 12
25. null;
26. end if;
27. Prim_Proc; -- OK.
28. Nonprim_Proc (Aaa); -- ERROR:
|
>>> "Nonprim_Proc" is not visible
>>> non-visible declaration at line 11
29. end;
30. end;
31.
32. end B840003;
(参见第27行)而与您的示例更相似的一个示例(将包声明拉到子程序的声明区域)则执行以下操作:
1. procedure B840003_Mod is
2. package Pkg_1 is
3. type Enum is (Aaa, Bbb, Ccc);
4. procedure Prim_Proc (X : Enum := Aaa) is null;
5. function Prim_Func return Enum is (Bbb);
6.
7. package Nested is
8. procedure Nonprim_Proc (X : Enum := Bbb) is null;
9. function Nonprim_Func return Enum is (Ccc);
10. end Nested;
11.
12. end Pkg_1;
13.
14. use all type Pkg_1.Enum;
15. begin
16. if Prim_Func /= Bbb then -- OK.
17. null;
18. end if;
19. if Nonprim_Func (Ccc) /= Ccc then -- ERROR:
|
>>> "Nonprim_Func" is not visible
>>> non-visible declaration at line 9
20. null;
21. end if;
22. Prim_Proc; -- OK.
|
>>> "Prim_Proc" is not visible
>>> non-visible declaration at line 4
23. Nonprim_Proc (Aaa); -- ERROR:
|
>>> "Nonprim_Proc" is not visible
>>> non-visible declaration at line 8
24.
25. end B840003_Mod;
参见第22行(过程调用;第16行的函数调用是可以的!)
这值得向AdaCore报告一个bug(尽管我不希望他们放弃所有东西并匆忙修复它)
有趣的是,早期版本的编译器(如GNAT CE 2018)发现
Bbb
,Ccc
不可见。我想知道第二个示例中的问题是否是Type\u包
不在库级别?(顺便说一下,它不是子包;Containers
是Ada.Containers
中的子包).另一方面,并不是说包必须在库级别-?只说使用Type\u package;
@SimonWright是的,Type\u package
在第二个示例中不在库级别。我想知道为什么使用Type
似乎只有在库级别时才起作用。而实例化库级别的泛型包。当我说子包时,我的意思是Type\u-package
在Use\u-Type
的声明部分声明。正确的术语是什么?使用整个包是可行的,但我很好奇如何只使用一个类型。@SimonWright在后一种情况下,编译器几乎不可用将操作视为T类型的基本操作。如果我举个例子并添加一个“=”操作,它会发现“使用所有类型”很好。我在RM中找不到任何可以清除此操作的内容。我觉得这样做应该是合法的,但只是一种感觉。