我正在开发一个基因程序,用Ada过滤数据 . 我尝试用列表和树来做到这一点 .
具有列表实现的程序运行良好 . 我的问题在于树 .
我有不同的通用包:
Arbre_Binaire_Recherche_g.ads
generic
TYPE Element IS PRIVATE;
WITH FUNCTION "="(E1,E2 : IN Element) RETURN Boolean;
WITH FUNCTION "<"(E1,E2 : IN Element) RETURN Boolean;
WITH PROCEDURE Liberer_Element(E : IN OUT Element);
WITH FUNCTION Element_To_String(E : IN Element) RETURN String;
package Arbre_Binaire_Recherche_g is
[...]
with function critere(E : in element) return Boolean;
procedure Filtrer(A : in Arbre; B : out Arbre);
private
TYPE Noeud;
TYPE Arbre IS ACCESS Noeud;
TYPE Noeud IS RECORD
Info : Element;
Gauche : Arbre;
Droite : Arbre;
END RECORD;
END Arbre_Binaire_Recherche_g;
这是过滤程序,通用函数为critere:
Arbre_Binaire_Recherche_g.adb
procedure Filtrer(A : in Arbre ; B : out Arbre) is
begin
if not Est_Vide(A) then
Filtrer(A.Gauche, B);
if critere(A.all.Info) then
Inserer_element(B, A.all.info);
end if;
Filtrer(A.Droite, B);
end if;
end Filtrer;
abr_acteurs.ads
WITH Arbre_Binaire_Recherche_G, Acteurs;
USE Acteurs;
package ABR_acteurs is new Arbre_Binaire_Recherche_G(acteur,"=","<",Liberer_acteur,Acteur_To_String);
还有 acteurs.ads 和 acteurs.adb 但这里并不重要 .
然后,客户端: Tester_ABR_Acteur :
WITH ABR_Acteurs, Acteurs, Ada.Text_Io, Arbre_Binaire_Recherche_G;
use Ada.Text_Io, Abr_Acteurs;
PROCEDURE Tester_ABR_Acteurs is
function Filtrage (Act : Acteurs.Acteur) return Boolean is
begin
return true;
end Filtrage;
procedure Filtrer_acteur is new Arbre_Binaire_Recherche_G.Filtrer(Filtrage);
[...]
但是,在编译时,会出现错误: invalid prefix in selected component "Arbre_Binaire_Recherche_G"
在线:
procedure Filtrer_acteur is new Arbre_Binaire_Recherche_G.Filtrer(Filtrage);
在客户端文件中 .
如果我做这个实例,那就有错误 . 但是,如果我将我的通用critere函数与其他通用过程/函数放在一起,如下所示:
Arbre_Binaire_Recherche_g.ads
generic
TYPE Element IS PRIVATE;
WITH FUNCTION "="(E1,E2 : IN Element) RETURN Boolean;
WITH FUNCTION "<"(E1,E2 : IN Element) RETURN Boolean;
WITH PROCEDURE Liberer_Element(E : IN OUT Element);
WITH FUNCTION Element_To_String(E : IN Element) RETURN String;
with function critere(E : in element) return Boolean;
然后我像这样实例化:
abr_acteurs.ads
package ABR_acteurs is new Arbre_Binaire_Recherche_G(acteur,"=","<",Liberer_acteur,Acteur_To_String, Critere_acteur);
没有错误,一切正常!
我找不到问题所在!
================================================== ==============
我的列表实现完全一样,在我的通用包的末尾使用泛型函数,它可以正常工作!我不明白..
有没有人有想法?
[ Update ]
- 我的通用函数: with function critere(E : in element) return Boolean; 在程序中: procedure Filtrer(A : in Arbre; B : out Arbre); ,就像这样:
procedure Filtrer(A : in Arbre ; B : out Arbre) is
begin
if not Est_Vide(A) then
Filtrer_hihi(A.Gauche, B);
Here there is critere(A.all.Info)
if critere(A.all.Info) then
Inserer_element(B, A.all.info);
end if;
Filtrer_hihi(A.Droite, B);
end if;
end Filtrer;
所以,如果我以这种方式实例化我的程序是正常的,因为(参见2.)
- 这就是我继续使用我的通用列表的方式:
包 liste_ordonnee_g.ads
with Ada.Unchecked_Deallocation;
generic
type Element is private;
with function "<"(E1, E2 : in Element) return Boolean;
with function "="(E1, E2 : in Element) return Boolean;
with procedure Liberer_Element(E : in out Element);
with function Element_To_String(E : in Element) return String;
package Liste_Ordonnee_G is
type Liste is private;
[...]
generic
with function Critere(E:Element) return Boolean;
function Filtrer(L : Liste) return Liste;
private
type Cellule;
type Lien is access Cellule;
type Cellule is record
Info : Element;
Suiv : Lien;
end record;
type Liste is record
Debut : Lien;
Cardinal : Natural;
end record;
-- procedure de liberation de la memoire occupee par la cellule
procedure Liberer_Cellule is new Ada.Unchecked_Deallocation(Cellule, Lien);
end Liste_Ordonnee_G;
liste_ordonnee_g.adb
function Filtrer(L : Liste) return Liste is
New_Liste : Liste;
Aux :Lien ;
begin
Creer_Liste(New_Liste);
Aux := L.Debut;
while Aux /= null loop
Here there is critere(A.all.Info)
if Critere(Aux.all.Info) then
Inserer(Aux.all.Info, New_Liste);
end if;
Aux := Aux.all.Suiv;
end loop;
return New_Liste;
end Filtrer;
在这里,我实例化我的通用包,没有函数critere:
liste_ordonnee_acteurs.ads
with Acteurs, Liste_Ordonnee_G;
use Acteurs;
PACKAGE Liste_Ordonnee_Acteurs IS new Liste_Ordonnee_G(Acteur, "<", "=", Liberer_Acteur, Acteur_To_String);
在我的客户端文件中:我使用 critere 实现我的通用过程 filtrer :
Test_Liste_Ordonnee_Acteurs.adb
function Filtrage (A : Acteurs.Acteur) return Boolean is
begin
return Acteurs.Annee(A) = 2000;
end Filtrage;
function Filtrer is new Liste_Ordonnee_Acteurs.filtrer(Filtrage);
列表实现正常工作!我不明白为什么树实现不起作用:( ..
2 回答
对于列表版本,您有
这有效地导致了新的通用函数
Liste_Ordonnee_Acteurs.Filtrer
你成功实例化的
您在树版本中所做的相当于
所以你需要改变
至
Arbre_Binaire_Recherche_G
是您的通用包的名称 . 通用包不是包;它是一个模板,您可以通过实例化它来创建包(定义实例) .Filtrer
是通用包中声明的非泛型过程 .当你写:
你试图从不是包的东西中引用
.Filtrer
名称 - 而Filtrer
本身甚至不是通用的 .如果您实例化
Arbre_Binaire_Recherche_G
包,则可以参考该实例中定义的Filtrer
函数(这是一个包):(但是从通用包中,泛型包的名称是指当前实例,而不是泛型,因此
Arbre_Binaire_Recherche_G.Filtrer
是该上下文中的有效过程名称 . 我'm not sure whether that'与您的问题相关 . )