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

在客户端文件中。


如果执行此操作,则有错误。 但是,如果我将通用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)返回布尔值; 在以下过程中: 过程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);

在我的客户端文件:我实例化与搜索标准我的通用过程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); 

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

===============>>#1 票数: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 在该上下文中是有效的过程名称。我不确定这是否与您的问题有关。 )

===============>>#2 票数:2 已采纳

对于列表版本,您有

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

  ask by papay0 translate from so

未解决问题?本站智能推荐:

2回复

Ada通用形式子程序

我正在上学的Ada作业。 我的老师为我提供了以下代码。 这是用于通用树。 我在测试文件中创建了一个新的通用树。 现在我得到以下错误。 我知道我应该某处,不知怎么实现这个过程put ,但在何处以及如何?
2回复

在Ada中构建二进制表达式树

我试图在Ada中使用完全带括号的中缀表示法构建表达式树。 我正在递归地构建树。 每个节点都有一个数据字段,以及一个指向左右子节点的指针。 以下是我汇总实施的内容。 我的问题是,当我输入一个表达式,例如,((5 + 6)*(1-3))时,树的构建不正确。 从该表达式构建的树的顺序遍
1回复

使用ada中静态库中的包

我想使用位于静态库中的包中的类型和服务。 因此,在我的身体main.adb中, Service.A位于外部库(services.a)中,因此在编译过程后需要链接该库。 我添加了标志-L/path/of/dir/containing/my/lib -lservices -L/p
2回复

在Ada的二叉树中寻找叶子

我已经用Ada编写了BSt,并且正在尝试打印叶子。 这是树和节点代码 我可以检查Tree是否不为null,但是如果我检查Tree.Left或Tree.Right是否为null,我会得到 符合例如 如何检查节点是否没有子节点?
1回复

这个Ada程序有什么错误?

此Ada2012程序有什么错误? 尝试检查语法和语义: 据我了解, First被我覆盖。 我没有得到编译器抱怨的东西。
2回复

Ada - 一维数组运算

参考John Barnes的书“ Ada 2012中的编程 ”(ISBN:978-1-107-42481-4),第138页(第8.6节)。 procedure ArrayOps is type Bit_Row is array (Positive range <>) of Bo
1回复

Ada类型声明语义

我正在上大学的Ada。 今天,我的教授向我们提出了一个问题。 在下面的代码中,有三个类型声明。 第三个没有编译错误“缺少新内容”。 我假设关键字'Type'让编译器知道我们即将定义存储类,所以我的问题是: 声明之间的语义差异是什么? 如果省略关键字Integer,则在指定范
1回复

Ada 2012中正式不完整类型的规则

根据AI05-213 ,现在可以使用不完整类型来实例化泛型。 我想用它来构建不透明的容器:几个包定义私有类型和匹配容器。 但是,我希望容器派生自一个常见的Containers.Container类型,它可以提供一些简单的子程序(例如Clear,Is_Empty,Iterate)。 对于后者
1回复

在Ada 95中创建通用子包

我有包p1和两个子包: p1.child1和p1.child2所有包都是通用的。 我正在尝试在p1.child2创建p1.child1的实例: 我收到一个错误: Instansiation of "p1" within itself 。 如何在p1.child1创建通用包p1.chi
2回复

从Ada中的两种类型继承

假设我有: 那我就生两个孩子 1。 2。 在这里,child和child2都从同一个父级继承,我想创建一个child3,其类型与something2相同,并从something3向其添加过程Z。 能做到吗 如何? 谢谢。