C++ Can';在另一个类中不使用类作为模板类型?

C++ Can';在另一个类中不使用类作为模板类型?,c++,C++,我有一个类堆栈,使用模板,它的方法之一是“push”,如下所示: template <class T> void Stack<T>::push(T _data){ Node<T>* temp = new Node<T>; temp->data = _data; temp->next = head; head = temp; } 当我使用类“树”作为数据类型时。 我不明白,为什么它与“string”一起工

我有一个类堆栈,使用模板,它的方法之一是“push”,如下所示:

template <class T>
void Stack<T>::push(T _data){
    Node<T>* temp = new Node<T>;
    temp->data = _data;
    temp->next = head;
    head = temp;
}
当我使用类“树”作为数据类型时。 我不明白,为什么它与“string”一起工作,而与“Tree”不一起工作,它们都是类,而不是基本类型

(忽略另一个错误,我的IDE在第32行只给出一个错误和一些警告)


救命啊

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

查看代码,尝试使用
新节点,它需要T的默认构造函数(在本例中为
),因为节点模板包含T的实例:

struct Node {
    T data;    // <--- instance of T, not being initialized in your code.
    Node *next;
};
这两种方法之间的选择是相当基本的。如果您让节点存储指向T的指针/引用,那么调用代码将负责确保传递的对象在节点存在时保持有效。节点和调用代码将共享对T的单个实例的访问

相反,如果将传递的对象复制到节点中,则当
节点
被销毁时,此副本将被销毁。传递给节点的原始T(在您的例子中是树)将仍然由调用代码负责,而
节点将负责其副本


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

在阅读实际代码后进行编辑(上面显示的“注意事项”对实际问题有相当大的误导性)

查看代码,尝试使用
新节点,它需要T的默认构造函数(在本例中为
),因为节点模板包含T的实例:

struct Node {
    T data;    // <--- instance of T, not being initialized in your code.
    Node *next;
};
这两种方法之间的选择是相当基本的。如果您让节点存储指向T的指针/引用,那么调用代码将负责确保传递的对象在节点存在时保持有效。节点和调用代码将共享对T的单个实例的访问

相反,如果将传递的对象复制到节点中,则当
节点
被销毁时,此副本将被销毁。传递给节点的原始T(在您的例子中是树)将仍然由调用代码负责,而
节点将负责其副本


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

您是否有
树的默认构造函数?如果不是,这可能是您的问题:节点在其
数据
成员中保存一个
类型,当您调用
新节点
时,该类型必须是默认构造的


要修复此问题,您可以修改
节点的构造函数,将
数据
下一步
作为参数,这样您就不需要在其模板类型上使用默认构造函数(您仍然需要赋值运算符才能使用)。

是否有
的默认构造函数?如果不是,这可能是您的问题:节点在其
数据
成员中保存一个
类型,当您调用
新节点
时,该类型必须是默认构造的


要修复此问题,您可以修改
节点的构造函数,将
数据
下一步
作为参数,这样您就不需要在其模板类型上使用默认构造函数(您仍然需要赋值运算符才能使用)。

我想我不熟悉gcc的注释,但这不会改变我回答的有效性。它不是“注意”(如果您将其称为“警告”),但有一个错误(导致程序无法编译)所以我肯定需要修复它。无论如何,树类的defaut构造函数正是我错过的。谢谢!请查看我编辑的答案——查看他在IDEONE上发布的内容,他发布的内容只是一个注释,但它与实际错误有关,在代码正常工作之前确实需要修复。我为仅基于在查看实际代码之前,问题是什么。@JerryCoffin-没问题,我以前也没有看过ideone代码:)我想我不熟悉gcc的注释,但这不会改变我回答的有效性。这不是一个“注释”(如果你提到“警告”),而是一个错误(导致程序无法编译)所以我肯定需要修复它。无论如何,树类的defaut构造函数正是我错过的。谢谢!请查看我编辑的答案——查看他在IDEONE上发布的内容,他发布的内容只是一个注释,但它与实际错误有关,在代码正常工作之前确实需要修复。我为仅基于在查看实际代码之前,问题是什么。@JerryCoffin-没问题,我之前也没有查看过ideone代码:)+1用于对不同选项及其含义的详细解释+1用于对不同选项及其含义的详细解释
class Node { 
    T data;
    Node *next;
public:
    Node(T const &dat) : data(dat), next(0) {}
};