我正试图在Ada中建立一个通用Node类的通用链表。但是,尽管使用了with
子句并使用了相应的前缀,但我无法访问链表中Node的类型和形式参数。
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;
genericsl.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
关于泛型广告。有什么建议吗?谢谢
对于Ada中的泛型包,您需要首先实例化它们。GenericNode不是包;这是一个包的配方,给定类型item_type。这两个错误都表明了这个问题;编译器正确地声明不存在这样的包并且不存在这样类型的NodePtr。("所选组件GenericNode中的有效前缀"只是意味着我不知道你所说的"GenericNode"是什么意思(
在C++中,你可能确实希望在节点类型上参数化你的单链表,然后告诉编译器"只获取这个节点类型的X和Y成员,尽管我还没有告诉你节点类型实际上是什么",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;