This question already has answers here:
Where and why do I have to put the "template" and "typename" keywords?
(8 answers)
Closed last month.
I am really sorry if this is a duplicate post, but I am really stuck on this particular problem. For some inexplicable reason the compiler does not understand what return type Node* is on the .cpp file, here is the code:
template<typename T>
Node* BinarySearchTree<T>::DiveDownToReplace(Node* node) {
if (node->leftChild->rightChild == nullptr) {
return node->leftChild;
}
//otherwise
Node* traversingNode = node->leftChild;
Node* returnedNode;
while (true) {
if (traversingNode->rightChild->rightChild == nullptr) {
returnedNode = traversingNode->rightChild;
traversingNode->rightChild = returnedNode->leftChild;
returnedNode->leftChild = nullptr;
break;
}
traversingNode = traversingNode->rightChild;
}
return returnedNode;
}
Here is also the code in the .h(header file):
#pragma once
template<typename T>
class BinarySearchTree {
private:
struct Node
{
T data;
Node* leftChild;
Node* rightChild;
};
int m_Length = 0;
Node* root = new Node();
public:
enum class TraverseMethod
{
preorder,
inorder,
postorder,
levelorder
};
~BinarySearchTree();
void AddElement(T value);
T RemoveRoot();
bool RemoveElement(T value);
void PrintAllElements(TraverseMethod traverseMethod);
bool IsEmpty();
bool GetSize();
bool Contains(T value);
private:
void PreOrder(Node* node);
void InOrder(Node* node);
void PostOrder(Node* node);
void LevelOrder(bool deleteNode = false);
void DiveDownToAdd(T value, Node* node);
Node* DiveDownToReplace(Node* node);
};
I am getting the error "identifier Node is undefined". I tried adding BinarySearchTree::Node* instead of Node*, but I received some weird errors(c2061, syntax error: identifier 'Node'). Once more I am sorry if this post is duplicate, but coming from languages like c# and Java I am really fed up with these header issues. Thank you in advance!
There are two rather complicated technical details of C++ that get combined together here. First of all, is scoping and namespaces.
//otherwise
Node* traversingNode = node->leftChild;
This is code that's inside a member function of the BinarySearchTree template. When a symbol, such as Node gets used the compiler needs to know what in blazes is that. BinarySearchTree defines an inner class named Node, so there you go. Problem solved.
template<typename T>
Node* ...
But what the heck is this? What is this weird Node all about? This part of the C++ code is not inside a member function. You better have a global class, or something, named Node, or you'll be in big trouble.
Just because there happens to be some class or template that's defined, and it has an inner class named Node, well this means absolutely nothing, whatsoever. When some symbol name is used, in global scope, the compiler is not going to search every class for something that happens to have the same name. C++ does not work this way.
And that's why you must spell everything out:
template<typename T>
typename BinarySearchTree<T>::Node *
The "template<typename T>" stuff makes a grandiose entrance of a template parameter that's represented by symbol T, and BinarySearchTree<T>::Node spells everything out.
And the second part of this story, the only remaining question here, is what in blazes is that typename all about.
Well, that's a long story, that you can read by yourself.
Related
I know there are many questions about that issue but nothing seems to work for me or it's too complex for me to understand.
So I have template Node
template <typename T>
class Node {
public:
T value;
Node* right;
Node* left;
Node(T value, Node<T>* right, Node<T>* left);
};
And Tree
template <typename T>
class Tree {
public:
Node<T>* root;
Tree();
~Tree() {}
void insert(T value);
Node<T>* search(T value, Node<T>* root) noexcept(false);
};
Now I want to create different Tree templates basing on what the user chose. Users can choose int, double, or string, these are the only options. I tried to use base class solution but my problem is that Tree uses type T in functions (and in Node) so I don't know how I should declare them in, let's call it BaseTree. Then I would be able to something like this:
BaseTree* tree;
tree = new Tree<int>();
I'm looking for a simple solution, I'm sort of beginner and it surprises me how this simple issue is so difficult for me to solve.
The solution is to templatize the generic functions also. Let's say you have something like this in mind:
void traverse(BaseTree const& tree) noexcept {
/* Logic here */
}
Instead, you do:
template<typename T>
void traverse(Tree<T> const& tree) noexcept {
/* Logic here */
}
This also helps that you can use Node<T> to refer to the node instead of fabricating BaseNode and whatnot again.
I am so sorry, I know this has been asked before, but even if I tried reading all the other answers to similar questions I can't understand my error.
I am using Eclipse, I am programming in C++ and I am trying to make a linked list using templates.
I am using a node class that will be useful for my linked list, and I have this function specification:
template <class item>
void list_insert(node<item>*& head, const item&e);
Allright. I want to use this function SO in my list class I can have this:
template <class item>
class list{
public:
list(){head=NULL;}
void set_head(node<item>*h){head=h;}
node<item>*& get_head(){return head;}
const node<item>* get_head()const{return head;}
bool empty()const{return head==NULL;} // is the list empty?
void insert(const item&e){list_insert(head,e);} //ERROR GETS HERE!
void print(); // print the list clockwise
void printback(); //print it counterclockwise
private:
node<item>* head;
};
I do that so I can implement list_insert like this:
template <class item>
void list_insert(node<item>*& head, const item& e){
head= new node<item>(e,head);
}
Now, in this last piece of code I get this error:
error: binding 'const int' to reference of type 'int&' discards qualifiers
I have read that basically the compiler is telling me ''ehi, if you do that, the const condition you wanted will be violated, so I give you an error'', allright, but still I don't understand the actuall error, or, anyway, what is the reasoning behind it.
Also because I am supposed to do a counterclockwise insert function too, but I am having troubles with the clockwise actually, so I am pretty stuck.
Thank you so much in advance.
EDIT: I am so sorry I did not provide actual example of what I am doing.
Basically, I am trying to make a linked list - simply and basic for my exam.
My linked-list is basically a stack made of nodes. Nodes are the component of my list, that are made of a data part and a link to the next node part:
template <class item>
class node{
public:
//CONSTRUCTOR
nodo(item & d=item(), nodo*l=NULL){
data=d;
link=l;
}
//GET E SET METHODS
void set_data(item& d){data=d;}
void set_link(node*l){link=l;}
item& get_data(){return data;}
const item& get_data()const{return data;}
node*& get_link(){return link;}
const node* get_link()const{return link;}
private:
item data;
node* link;
};
Now, as said my list is made of nodes and in the private part I declared a pointer to the head of the list.
node<item>* head;
That is the example of this code-- and then the problem occurs as I wrote before.
In the constructor of node you should pass item by const-reference (and there is some typo, perhaps a copy+paste error in your node class.
class node{
public:
//CONSTRUCTOR
node(item const & d=item(), node*l=0)
: data(d), link(l) // prefer initializer list here
{ }
//...
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
There are many errors in my codes.
But i don't know about wrong things...
There are common error massages such that "invalid use of template-name
‘node’ without an argument list", "‘head_ptr’ was not declared in this
scope", "‘tail_ptr’ was not declared in this scope",
"‘t’ was not declared in this scope" ,
"template argument 1 is invalid", "expected type-specifier before ‘Node’"
I don't think my overall code is wrong.
But too many error make me to think
all of composition of coding is error..
It is a part of all code.
error explanation
template <typename T>
Node* Node<t>::getNext(void)
{ return next; }
template <typename T>
class List
{
private:
Node* head_ptr; Node* tail_ptr; int numOfItems;
public:
List(); //constructor
int size(void); bool isEmpty(void);
void insertTail(T x);
void removeHead(void);
Node<T>* getHead(void);
Node<T>* getTail(void);
void insert_with_priority(T x);
};
template <typename T>
List<T>::List()
{ head_ptr = NULL; tail_ptr = NULL; numOfItems = 0; }
template <typename T>
void List<T>::insertTail(T x){
Node<t>* newTail = new Node(x);
tail_ptr->setNext(newTail);
tail_ptr = newTail;
numOfItems++;
}
template <typename T>
void List<T>::removeHead(void){
if(numOfItems == 0)
return 0;
if(numOfItems == 1){ //i.e. headptr == tail_ptr
delete head_ptr; head_ptr = NULL; tail_ptr = NULL;
'
Please give me many feedback.
Even though your question is incomplete, I'll help you with one of the errors (and it might solve other follow-up errors as well)...
Lets take the lines
template <typename T>
Node* Node<t>::getNext(void)
{ return next; }
You say that the getNext function returns a pointer to Node. But, in this instance what is Node? It's not a class or a type, it's a template for a class or type. It's not complete. You need to specify the full and complete class or type:
template <typename T>
Node<T>* Node<t>::getNext(void)
{ return next; }
Note the return-type which is now a full class.
I am making a tree of n children to store directories of computer. Now, concept is simply make a tree (that would not be a BT of course) and each node will have children as well. Consider the code below then I will explain the problem.
First Consider this:
C/users/DeadCoder/Movies/Batman.
Now In my main.cpp I have this all C, users, DeadCoder, Movies, Batman in a vector and then I send two pairs in insert Func. if root==NULL; it would just insert C. Next time C and users would go. It would find C and then insert users occordingly. Let's now see the code .
template <class T>
struct Node;
template <class T>
class tree
{
Node<T> *root;
public:
tree();
~tree();
int insert(T str, T str1);
Node<T> *getRoot();
Node<T> *search(T item, Node<T> *tempPtr);
};
template <class T>
struct Node{
T n;
Node<T> *sibling;
tree<T> children; // SEE my each node has children.
Node(T N){
this->n = N;
this->sibling = NULL;
}
};
// In .cpp FILE;
// Initilaizer
template <class T>
tree<T>::tree() // Constructor Initialization.
{
root=NULL;
}
// Insert Function.
template <class T>
int tree<T>::insert(T push, T find)
{
Node<T> *rPtr = root;
if (rPtr==NULL){
//ROOT is NULL. C needs to be inserted which is in find.
Node<T> *pusPtr = new Node<T>(find);
root = pushPtr;
root->sibling=NULL;
return 0;
}
else if(rPtr!=NULL){
Node<T> *pushPtr = new Node<T>(push);
Node<T> *temp2 = search(find, root);
Node<T> *temp = temp2->children.getRoot(); // say it LINE_40.
if (temp==NULL){
temp = pushPtr;
temp->sibling=NULL;
return 1;
}
// children are already present.
else if(temp!=NULL){
// You don't need to know code for this part.
}
}//if.
}
// Search Function.
template <class T>
Node<T> *tree<T>::search(T data, treeNode<T>* N)
{
if (N->n==data){ // where n represent directory.
return N; // data found.
}//if....
else{
Node<T> *child = N->children.getRoot();
// This is where i get Segmentation fault,
// because child is ==NULL; but you see in LINE_40 I did insert the child for C.
if(child!=NULL){ // say it line 80.
search(data, child);
}//if...
if(child->sibling!=NULL){
search(data, child->sibling);
}
}
}// search....
PROBLEM: C inserted. Users inserted. Now in search function at Line 80, it comes to find the child for C. and it should be Users as I have inserted it in LINE 40. BUT Instead it says child==NULL. I have been debugging for hours and I don't know why it says so. I hope Everybody gets the problem.
Now I really need to know why it is regarding C child to be NULL, It has to be users. Can anyOne see what is the problem???? HELP !!!!
Line 42 does nothing (I mean it has no side effect). It just puts a value in a temporary variable then leaves.
You probably want your temp to be a reference to the root. Something like: Node<T> *&temp =
Are you sure insert method actually inserted these elements?
It might be helpful to implement postconditions so to verify your methods actually fulfill their contract (design by contract).
This way you'll directly get what is wrong and debugging will be fast or unnecessary in some cases, since you'll get log messages saying "this method was supposed to do this but failed doing it", otherwise you'll look for hours where the problems comes from.
I am getting this message with everything that has Node* (this declaration has no storage or type specifier). Could somebody help and please send me in the right direction?
template <typename type>
Node* Stack<type>::pop() {
Node* retNode; // the node to be return
if(tos == NULL) {
cerr << "*** Stack empty ***";
exit(1);
}
else {
retNode = tos; // store the location of tos
tos = tos->getLink(); // move to new tos
retNode->setLink(); // unlink the popped node from the stack
size -= 1;
}
return retNode;
}
I am sure it's dealing with Node* but I just can't figure out what.
Below are my declarations for the node class that are being used in my stack class. Let me know if you need my declarations for the stack class as well because I just cant see the problem.
template <typename type>
class Node<type>{
private:
type data;
Node *link;
public:
Node(type p_item, Node *p_link);
type getData() const;
Node* getLink() const;
void setData(type p_data);
void setLink(Node *node);
};
Node is a class template, so you cannot use Node or Node * as data types. You must add template arguments in angle brackets, e.g. Node<int> or Node<char> * etc.
In the specific example you gave, it seems the following would be appropriate:
template <typename type>
Node<type>* Stack<type>::pop() {
Node<type>* retNode;
/* ... */
return retNode;
}
I.e. the same type argument that is used for Stack should (probably) be used for Node as well.
Two further notes:
It seems odd that, while the Node template appears to implement internal data structures of your stack, Node<type> * pointers are returned by the pop function of the stack. It would seem more natural (and better encapsulation, and more intuitive for the users of your stack) to return type objects.
It also seems odd that the pop function calls exit (and thus brings the entire process to a halt) when the stack is empty. Perhaps returning nullptr, or a dummy object, or throwing an exception (or a similar strategy) would be more appropriate.