我正在开发一个通用程序,该程序可以使用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);
[...]

但是,在编译时,会出现错误:
所选组件“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);

没有错误,一切正常!

我找不到问题所在!

================================================== ==============
我对列表实现完全相同,在通用包的末尾使用通用函数,并且可以正常工作!我不明白

有人有主意吗?

[更新]
  • 我的通用函数:带有函数critere(E:in element)的返回 bool(boolean) 值; 在过程中:过程Filtrer(A:进入Arbre; B:离开Arbre); ,像这样:
    procedure Filtrer(A : in Arbre ; B : out Arbre) is
       begin
     if not Est_Vide(A) then
        Filtrer_hihi(A.Gauche, B);
    

  • 这里是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
    

    这里是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);
    

    列表实现正常工作!我不明白为什么树实现不起作用:( ..

    最佳答案

    对于列表版本,您有

    with Acteurs, Liste_Ordonnee_G;
    use Acteurs;
    PACKAGE Liste_Ordonnee_Acteurs
       IS new Liste_Ordonnee_G(Acteur, "<", "=", Liberer_Acteur, Acteur_To_String);
    

    (有效地)产生了一个新的通用函数Liste_Ordonnee_Acteurs.Filtrer,例如
    generic
       with function Critere(E:Acteur) return Boolean;
    function Filtrer(L : Liste) return Liste;
    

    您成功实例化为
    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);
    

    您在树形版本中所做的等同于
    function Filtrer is new Liste_Ordonnee_G.filtrer(Filtrage);
    

    所以你需要改变
    procedure Filtrer_acteur is new Arbre_Binaire_Recherche_G.Filtrer(Filtrage);
    


    procedure Filtrer_acteur is new ABR_Acteurs.Filtrer(Filtrage);
    

    08-07 00:44