I have a class Stack, using template, one of its methods is “push”, which is written below:
template <class T>
void Stack<T>::push(T _data){
Node<T>* temp = new Node<T>;
temp->data = _data;
temp->next = head;
head = temp;
}
The stack works well with int, double, string, char….
But it says
prog.cpp:32: note: synthesized method ‘Node<Tree>::Node()’ first required here
when I use a class “Tree” as data type.
I don’t understand, why it works with “string” but not with “Tree”, they are both classes, not primitive types.
http://ideone.com/NMxeF
(Ignore the other error, my IDE only gives one error at line 32 and some warnings)
Help!
Edit after reading the actual code (the “note” shown above is fairly misleading about the real problem).
Looking at the code, where you try to use
new Node<T>;, that needs a default constructor for T (which in this case isTree) because your Node template contains an instance of T:Treedoesn’t have a default constructor, so that fails (and the note is showing you where the default constructor would be needed).You have a few choices about how to fix that. The most obvious would be for a
Nodeto hold either a pointer or a reference to aTinstead of containing an actual instance of T.Another would be to have
Node‘s constructor take a reference to a (probably const) T, and copy that T into the Node:The choice between these two approaches is fairly fundamental. If you have Node store a pointer/reference to T, then it will be the responsibility of calling code to ensure the passed object remains valid as long as the Node exists. The node and calling code will share access to a single instance of T.
By contrast, if you copy the passed object into the Node, then this copy will be destroyed when the
Nodeis destroyed. The original T (Tree, in your case) you passed to the Node will remain the responsibility of the calling code, and theNodewill take responsibility for its copy.In the usual case, you’d tend to favor the latter — it gives cleaner semantics, and keeps ownership of the data clear. In the case of a Tree, however, you probably don’t want to copy an entire tree into a Node if you can avoid it. One compromise position would be to use something like a
Node<shared_ptr<Tree> >instead. The shared_ptr can keep copying fast and cheap, while avoiding writing a Node that’s only suitable for a few kinds of objects and situations. That also makes fairly explicit that you’re storing only a pointer that gives shared access to the original object.