【问题标题】:Ada : invalid prefix in selected componentAda:所选组件中的无效前缀
【发布时间】:2014-04-19 23:14:19
【问题描述】:

我正在开发一个用 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.adsacteurs.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);  

在客户端文件中。


如果我执行此实例化,则会出现错误。 但是,如果我将我的通用标准函数与其他通用过程/函数放在一起,就像这样:

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);

没有错误,一切正常!

我找不到问题出在哪里!

================================================ =================
我的列表实现完全相同,在我的通用包末尾使用通用函数,它可以正常工作!没看懂。。

有人有想法吗?

[更新]

  • 我的通用函数: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);
    

这里有条件(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

这里有条件(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;

在这里,我在没有函数标准的情况下实例化了我的通用包:

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);

在我的客户端文件中:我用 critre 实例化了我的通用过程 filter

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); 

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

【问题讨论】:

    标签: generics filter compiler-errors tree ada


    【解决方案1】:

    对于列表版本,您有

    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 like

    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);
    

    【讨论】:

    • 谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢!当然是这样!有时候,我可能很愚蠢!再次感谢您;-)!!
    【解决方案2】:

    Arbre_Binaire_Recherche_G 是您的通用包的名称。通用包不是包;它是一个模板,您可以从中通过实例化它来创建一个包(定义一个实例)。

    Filtrer 是在泛型包中声明的非泛型过程。

    当你写作时:

    procedure Filtrer_acteur is new Arbre_Binaire_Recherche_G.Filtrer(Filtrage);
    

    您试图从不是包的东西中引用 .Filtrer 名称 - 而 Filtrer 本身甚至不是通用的。

    如果您实例化您的 Arbre_Binaire_Recherche_G 包,则可以参考该实例(这是一个包)中定义的 Filtrer 函数:

    package Actual_Package is new Arbre_Binaire_Recherche_G(...);
    ...
    ... Actual_Package.Filtrer ...
    

    (但是在泛型包中,泛型包的名称指的是当前实例,而不是泛型,因此Arbre_Binaire_Recherche_G.Filtrer 是一个有效的过程名称​​在该上下文中。我'我不确定这是否与您的问题有关。)

    【讨论】:

    • 我想他已经有一个Actual_Package,即ABR_acteurs。这才是他应该使用的。 (另外,我认为Filtrer 实际上可能是一个通用过程,因为它之前的with function;关键字generic 可能隐藏在[...] 中。)
    猜你喜欢
    • 2016-01-04
    • 1970-01-01
    • 2022-11-24
    • 2021-06-19
    • 2013-02-04
    • 1970-01-01
    • 2022-01-24
    • 2014-04-16
    • 1970-01-01
    相关资源
    最近更新 更多