Ada 通用链表和通用包访问
Ada Generic Linked List and Generic Package Access
我正尝试在 Ada 中基于通用节点 class 构建通用链表。但是,尽管使用了 with
子句并相应地添加了前缀,但我无法在我的链表中访问我的节点的类型和形式参数。
genericnode.ads:
generic
type item_type is private;
package GenericNode is
type Node is limited private;
type NodePtr is access Node;
procedure GetData(n : in Node; e : out item_type);
procedure GetNext(n : in Node; x : out NodePtr);
procedure SetData(n : in out Node; e : in item_type);
procedure SetNext(n : in out Node; x : in NodePtr);
private
type Node is
record
data : item_type;
next : NodePtr;
end record;
end GenericNode;
genericsll.ads:
with GenericNode;
generic
size : Positive;
type node_type is private;
package GenericSLL is
type SLL is limited private;
procedure Append(s : in out SLL; d : in GenericNode.item_type);
procedure PrintTraversal(s : in SLL);
private
type SLL is
record
head : NodePtr := null;
length : Positive := 0;
end record;
end GenericSLL;
编译后,我被告知 Invalid prefix in selected component "GenericNode"
和 "NodePtr" is not visible
关于 genericsll.ads。有什么建议么?谢谢!
对于 Ada 中的通用包,您需要首先实例化它们。 GenericNode 不是一个包;它是包的配方,给定类型 item_type。这两个错误都表明存在这个问题;编译器正确地指出没有这样的包,也没有这样的 NodePtr 类型。 ('invalid prefix in selected component GenericNode' 只是表示我不知道你所说的 'GenericNode' 是什么意思)
在 C++ 中,您可能确实希望在节点类型上对单向链表进行参数化,然后告诉编译器“只获取此节点类型的 X 和 Y 成员,即使我没有告诉你实际上是什么节点类型 是 yet',Ada 编译器拒绝这个,因为它会导致容易出错的代码,你无法判断类型应该满足什么(C++20 中的约定旨在解决此问题)。
艾达不允许这样做;每个包都必须在使用前实例化,以便知道每种类型的参数。不幸的是,这也意味着无法像在 C++ 中那样在 Ada 中进行任意编译时计算。
如果您在 item_type 而不是 node_type 上参数化 GenericSLL,它可以使用 item_type 实例化它需要的特定 GenericNode 包。只需要修改GenericSLL:
with GenericNode;
generic
size : Positive;
type item_type is private;
package GenericSLL is
package LinkedList_Node is new GenericNode(item_type);
use LinkedList_Node;
type SLL is limited private;
procedure Append(s : in out SLL; d : in item_type);
procedure PrintTraversal(s : in SLL);
private
type SLL is
record
head : NodePtr := null;
length : Natural := 0; -- Positive starts at 1
end record;
end GenericSLL;
我正尝试在 Ada 中基于通用节点 class 构建通用链表。但是,尽管使用了 with
子句并相应地添加了前缀,但我无法在我的链表中访问我的节点的类型和形式参数。
genericnode.ads:
generic
type item_type is private;
package GenericNode is
type Node is limited private;
type NodePtr is access Node;
procedure GetData(n : in Node; e : out item_type);
procedure GetNext(n : in Node; x : out NodePtr);
procedure SetData(n : in out Node; e : in item_type);
procedure SetNext(n : in out Node; x : in NodePtr);
private
type Node is
record
data : item_type;
next : NodePtr;
end record;
end GenericNode;
genericsll.ads:
with GenericNode;
generic
size : Positive;
type node_type is private;
package GenericSLL is
type SLL is limited private;
procedure Append(s : in out SLL; d : in GenericNode.item_type);
procedure PrintTraversal(s : in SLL);
private
type SLL is
record
head : NodePtr := null;
length : Positive := 0;
end record;
end GenericSLL;
编译后,我被告知 Invalid prefix in selected component "GenericNode"
和 "NodePtr" is not visible
关于 genericsll.ads。有什么建议么?谢谢!
对于 Ada 中的通用包,您需要首先实例化它们。 GenericNode 不是一个包;它是包的配方,给定类型 item_type。这两个错误都表明存在这个问题;编译器正确地指出没有这样的包,也没有这样的 NodePtr 类型。 ('invalid prefix in selected component GenericNode' 只是表示我不知道你所说的 'GenericNode' 是什么意思)
在 C++ 中,您可能确实希望在节点类型上对单向链表进行参数化,然后告诉编译器“只获取此节点类型的 X 和 Y 成员,即使我没有告诉你实际上是什么节点类型 是 yet',Ada 编译器拒绝这个,因为它会导致容易出错的代码,你无法判断类型应该满足什么(C++20 中的约定旨在解决此问题)。
艾达不允许这样做;每个包都必须在使用前实例化,以便知道每种类型的参数。不幸的是,这也意味着无法像在 C++ 中那样在 Ada 中进行任意编译时计算。
如果您在 item_type 而不是 node_type 上参数化 GenericSLL,它可以使用 item_type 实例化它需要的特定 GenericNode 包。只需要修改GenericSLL:
with GenericNode;
generic
size : Positive;
type item_type is private;
package GenericSLL is
package LinkedList_Node is new GenericNode(item_type);
use LinkedList_Node;
type SLL is limited private;
procedure Append(s : in out SLL; d : in item_type);
procedure PrintTraversal(s : in SLL);
private
type SLL is
record
head : NodePtr := null;
length : Natural := 0; -- Positive starts at 1
end record;
end GenericSLL;