不能将一个类用作另一个类中的模板类型?

Can't use a class as template type in another class?

本文关键字:另一个 类型 一个 不能      更新时间:2023-10-16

我有一个类栈,使用模板,它的方法之一是"push",下面写着:

template <class T>
void Stack<T>::push(T _data){
    Node<T>* temp = new Node<T>;
    temp->data = _data;
    temp->next = head;
    head = temp;
}

该堆栈适用于intdoublestringchar ...。但它说

prog.cpp:32: note: synthesized method ‘Node<Tree>::Node()’ first required here

当我使用类"树"作为数据类型时。我不明白,为什么它适用于"字符串"而不是"树",它们都是类,而不是原始类型。

http://ideone.com/NMxeF(忽略另一个错误,我的 IDE 仅在第 32 行给出一个错误和一些警告)

帮助!

阅读实际代码后进行编辑(上面显示的"注释"对实际问题具有相当大的误导性)。

查看代码,您尝试使用 new Node<T>; ,需要 T 的默认构造函数(在本例中为 Tree),因为您的 Node 模板包含 T 的实例:

struct Node {
    T data;    // <--- instance of T, not being initialized in your code.
    Node *next;
};

Tree没有默认构造函数,因此会失败(并且注释显示需要默认构造函数的位置)。

关于如何解决这个问题,您有几种选择。最明显的是Node保存指针或对T的引用,而不是包含 T 的实际实例。

另一种方法是让Node的构造函数引用一个(可能是常量)T,并将该T复制到节点中:

class Node { 
    T data;
    Node *next;
public:
    Node(T const &dat) : data(dat), next(0) {}
};

这两种方法之间的选择是相当基本的。如果你让 Node 存储指向 T 的指针/引用,那么只要 Node 存在,它就有责任调用代码以确保传递的对象保持有效。节点和调用代码将共享对 T 的单个实例的访问权限。

相反,如果将传递的对象复制到 Node,则在销毁Node时将销毁此副本。您传递给节点的原始 T(树,在您的情况下)仍将由调用代码负责,Node将对其副本负责。

通常情况下,你倾向于后者 - 它提供了更清晰的语义,并保持数据的所有权清晰。但是,对于树,如果可以避免,您可能不希望将整个树复制到节点中。一种折衷的立场是改用类似Node<shared_ptr<Tree> >的东西。shared_ptr可以保持快速和廉价的复制,同时避免编写仅适用于几种对象和情况的节点。这也相当明确地表明,您只存储一个指针,该指针提供对原始对象的共享访问权限。

你有

Tree的默认构造函数吗? 如果没有,那可能是你的问题:Node 在其data成员中保存一个 Tree 类型,当您调用 new Node<Tree> 时,该类型必须默认构造。

要修复,您可以修改 Node 的构造函数以将 datanext 作为参数,因此您不需要其模板类型的默认构造函数(您仍然需要赋值运算符可用)。

相关文章: