This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 8 years ago.
I'm trying to add a node onto the beginning of a linked list (push function). I'm getting 2 errors:
1) invalid conversion from 'Node int*' to 'int' (points to test.Push(&test2); in main())
2) initializing argument 1 of 'int Linked_List::Push(ItemType) [with ItemType = int]' (points to function push)
I'm really not sure what the problem is. If I remove the & out of test.Push(&test2); in main() then I get a lot more errors, so I assume it's correct.
//.h
#ifndef Linked_List_h
#define Linked_List_h
template <typename ItemType>
class Node
{
public:
ItemType Data;
Node <ItemType> *next;
};
template <typename ItemType>
class Linked_List
{
public:
Node <ItemType> *start;
Linked_List();
int Push(ItemType newitem);
};
#endif
.
//.cpp
#include "Linked_List.h"
template <typename ItemType>
Linked_List <ItemType>::Linked_List(){
start = NULL;
}
template <typename ItemType>
int Linked_List <ItemType>::Push(const ItemType newitem){ //error
Node <ItemType> *nnode; //create new node to store new item
nnode -> next = start -> next; //new item now points previous first item of list
start -> next = nnode; //'start' pointer now points to the new first item of list
return 1;
}
int main(){
Linked_List <int> test;
Node <int> test2;
test2.Data = 4;
test.Push(&test2); //error
}
Your function's signature expects a ItemType, which is int in your case:
int Push(ItemType newitem);
But you are trying to pass a Node<ItemType>, hence you get an error.
Your Push function is already creating a a node internally, so you'd pass the integer directly into it:
Linked_List <int> test;
int test2 = 4;
test.Push(test2);
I need to point out that your code has several other problems besides that, though - for starters, this snippet:
Node <ItemType> *nnode; //create new node to store new item
Does not create a Node - it just declares a pointer.
I'd strongly advise you to read up on C++'s basics.
Push takes the template type, so int in this case. What you want to do is something like:
Linked_List<int> test;
test.push(4);
Related
I have implemented a fairly simple idea of a double linked list. I don't know what am I doing wrong!
I have tried making the member variables of the node as public but doesn't help. Friend class doesn't help either. What is the nonclass type here?
d_list.h
#include "node.h"
#ifndef NODE_H
#define NODE_H
template<class T>
class d_list{
private:
int list_size;
T* head;
T* tail;
public:
//parametrized Default constructor
d_list(T* h=nullptr, T* t=nullptr):head(h),tail(t){}
//get Head of the List
T* gethead(){return this->head;}
T* gettail(){return this->tail;}
void addnodeastail(T* new_node){
if(this->head==nullptr){
this->head=new_node;//this->head will point towards new_node
this->tail=this->head;
this->list_size=list_size+1;
}
else{
this->tail= new_node;
this->tail->next=new_node->previous;
}
}
};
#endif
'''
node.h
template<class T>
class Node{
private:
Node* next;
Node* previous;
T data;
public:
Node()=default;
Node(T dta):data(dta){}
~Node(){}
};
main.cpp
#include<iostream>
#include"d_list.h"
using namespace std;
int main(){
d_list<int> d1;
cout<<d1.gethead()<<endl;
cout<<d1.gettail()<<endl;
int var=20;
int* n1= &var;
int var2 =40;
int* n2= &var2;
d1.addnodeastail(n1);
d1.addnodeastail(n2);
cout<<d1.gethead()<<endl;
cout<<d1.gettail()<<endl;
return 0;
}
Error which I am receiving is something like
In file included from main.cpp:2:
d_list.h: In instantiation of 'void d_list<T>::addnodeastail(T*) [with T = int]':
main.cpp:14:24: required from here
d_list.h:28:29: error: request for member 'next' in '*((d_list<int>*)this)->d_list<int>::tail', which is of non-class type 'int'
28 | this->tail->next=new_node->previous;
| ~~~~~~~~~~~~^~~~
d_list.h:28:44: error: request for member 'previous' in '* new_node', which is of non-class type 'int'
28 | this->tail->next=new_node->previous;
| ~~~~~~~~~~^~~~~~~~
With
template<class T>
class d_list{
private:
int list_size;
T* head;
T* tail;
you declare that head and tail are pointers to the template type T.
That means for d_list<int> you effectively have
int* head;
int* tail;
That makes no sense, your head and tail pointers should be pointers to the first and last nodes in the list:
Node<T>* head;
Node<T>* tail;
And when adding elements to the list, you need to create new Node<T> instances to hold the data, and add the nodes to the list.
The thing is that head and tail shouldn't be T, but rather node<T>:
Node<T>* head;
Node<T>* tail;
Remember, T is the type of object you want to hold in your list. It has no link associated with it. So if you do a d_list<int> currently as written, the templated code will look something like this:
int* head;
int* tail;
These are not linked to each other, this is just a pointer to an int (or a list of ints if you used something like new). To create a link, you need to use Node so o matter where in memory they are stored, they will have a logical connection. That way, d_list<int> would look something like this instead:
Node<int>* head;
Node<int>* tail;
This will let you use nodes to develop a logically connected list of ints, which is exactly what you want for a linked list.
I'm working on my final project for C++ and my professor specified that we had to have three class files for a linked list.
The first named LinkedList holds the head and the tail, as well as two overloaded operators in which we have to use the list as an array, and add an element to the end of the array.
The second named Node holds the two generic values Seat and Row.
The third and final named RNode holds the values of the next, previous spots in the list, as well as reservation status.
My problem is when using my LinkedList.cpp, defining all of the functions, I cannot figure out how to set node equal to the head, because the types are different. I can set the next node in the list with tempNode.setNext(Head);. But when I try to do tempNode = tempNode.getNext() it says the types are not the same. What is an easy way for me to make this work?
Here is my code.
This is supposed to use the Linked List as an array and return the pointer to the Node correlating with the integer passed in.
int& LinkedList::operator[] (const int &middle) {
RNode *tempNode;
tempNode->setNext(Head);
tempNode = tempNode->getNext(); // Error here
for (int i = 0; i < middle; i++) {
}
}
Here are the three class files I have currently made.
Linked List Class
#ifndef LINKEDLIST_H_INCLUDED
#define LINKEDLIST_H_INCLUDED
#include "Node.h"
class LinkedList {
private:
Node* Head; // Head of linked list
Node* Tail; // Tail of linked list
public:
// Constructors
LinkedList(); // Set default values
LinkedList(Node*, Node*); // Set values passed in to head and tail
int& operator [] (const int &); // Overloaded [] operator PAGE 854 HOW TO USE THIS
// Treat list like an array.
// First node will be [0]
// Return pointer to node indicated inside of brackets
Node& operator += (const Node &); // Overloaded += operator
// Adds a node to the end of the linked list
// Head
void setHead(Node*); // Sets head of list
Node* getHead(); // Returns the head of list
// Tail
void setTail(Node*); // Sets tail of list
Node* getTail(); // Returns tail of list
};
#endif // LINKEDLIST_H_INCLUDED
Reservation Node Class
#ifndef RNODE_H_INCLUDED
#define RNODE_H_INCLUDED
#include "Node.h"
using namespace std;
class RNode : public Node {
private:
Node* Next; // Next node pointer
Node* Prev; // Previous node pointer
bool reservationStatus(); // Reservation status
public:
// Constructors
RNode(); // Sets default values
RNode(Node*, Node*, bool); // Takes values passed in and sets them
// Overloaded operators
friend ostream &operator << (ostream &, Node*); // Prints out correct symbol based on reservation status
friend istream &operator >> (istream &, Node*); // Prints correct symbol based on reservation status .
// Next
void setNext(Node*); // Sets next node in list
Node* getNext(); // Returns next node in list
// Prev
void setPrev(Node*); // Sets previous node in list
Node* getPrev(); // Returns previous node in list
// Reservation Status
void setReservationStatus(bool); // Sets reservation status of a current node
bool getReservationStatus(); // Returns reservation status
};
#endif // RNODE_H_INCLUDED
Node Class
#ifndef NODE_H_INCLUDED
#define NODE_H_INCLUDED
class Node {
protected:
int row;
int seat;
public:
// Constructors
Node(); // Sets default values
Node(int, int); // Sets row and seat to values passed in
// Row
void setRow(int); // Sets row for current node
int getRow(); // Gets row for current node
// Seats
void setSeat(int); // Sets seat for current node
int getSeat(); // Gets seat for current node
};
#endif // NODE_H_INCLUDED
In summary, how can I match the types so that I can set RNode tempNode equal to a Node? This is very confusing and I can't really find a good explanation on how to solve this.
Keep in mind, according to my instructions I have to have the classes created this way. If it were up to me, I would have combined the RNode and Node class.
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
class sequence{
struct node{
string name;
string data;
struct node * next;};
sequence();
~sequence();
void print(struct node *);
struct node *sortlist(struct node *);
struct node *deletenode(struct node *, string);
struct node *searchnode(struct node *, string);
struct node *insertnode(struct node *, string);};
void print(struct node *st){ //method to print the linked list
while(st!=0){
cout<<st->data<<endl;
st=st->next;}}
struct node *deletenode(struct node *st, string x){//to delete a node containing element x
struct node *s1=st, *t,*ptr;
string m=x;
ptr=st;
if (s1==0)// if linked list is empty {
cout<<"linkedlist empty"<<endl;}
else if(s1->next==0)//if linked list contains only one element
{
if(s1->data==m)
{
free(s1);
s1=0;}
else
cout<<m<<"is not in the list."<<endl;
}
else if(s1->next!=0&&s1->data==m)
{
t=s1->next;
free(s1);
s1=t;
}
else
{
while(s1->data!=m&&s1->next!=0)
{
t=s1;
s1=s1->next;
}
if(s1->data==m)
{
t->next=s1->next;
free(s1);
s1=t;
}
else
cout<<m<<"is not in the list."<<endl;
}
return(ptr);
}
int main(){
sequence obj=new sequence();
struct node *root1, *root2, *root3, *s, *p,*t;
string v;
root1= new node;
root2= new node;
root3= new node;
s=root1;
root1->next=root2;
root2->next=root3;
root3->next=0;
root1->data="man";//data in the nodes of linked list
root2->data="aan";
root3->data="van";
root1->name="1";
root2->name="2";
root3->name="3";
cout<<"enter the string :";
cin>>v;
cout<<endl;
p=obj.deletenode(s, v);// delete node function call
obj.print(p);
return(0);}
Problem 1: when i am running this code, it executes with bug in deletenode method where it is not deleting the first element of linked list but deleting every other element.Please enlighten me where i am getting wrong in the code.
Problem 2: I was trying to create a class with all above mention methods, a constructor and a destructor but when i am running this code i am getting errors like "invalid use of incomplete type 'struct node'".I am new to the concept of classes kindly guide me where i am getting wrong in this code.
Apologies for no proper formatting.
looking for a positive reply.
well you are not supposed to define a whole Structure within the class definition
, instead of doing this define the structure publicly and include its instance within the class . Hope this Helps
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct node{ //structure definition outside the class
string name;
string data;
struct node * next;
};
class sequence{
node node1; //define a node variable
sequence();
~sequence();
void print(struct node *);
struct node *sortlist(struct node *);
struct node *deletenode(struct node *, string);
struct node *searchnode(struct node *, string);
struct node *insertnode(struct node *, string);};enter code here
I'm working on implementing linked list using c++. I created a struct Node inside my LinkedList.h, and try to overload operator in node. But when I compiled, I got this error
Code:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
class LinkedList{
typedef struct Node{
int data;
Node* next;
} * nodePtr;
//Returns true if the current Node object value is
//less than the parameter Node object value
bool operator < (const Node& node) const {
return this->data < node->data; <--- Unable to resolve identifier data.
};
#endif /* LINKEDLIST_H */
I don't know what I did wrong. Can someone tell me please?!
Thanks!
Although I would do this differently, the problem is that you don't define any place in your class to hold a Node structure. I'm not sure if you were trying for this or not:
class LinkedList{
typedef struct Node{
int data;
Node* next;
} * nodePtr;
Node node; // Added this
//Returns true if the current Node object value is
//less than the parameter Node object value
bool operator < (const Node& node) const {
return this->node.data < node.data;
}
};
It looks like you're trying to access something that doesn't exist. Your LinkedList implementation doesn't have a variable named data.
The simplest fix is to change your operator body:
return this->nodePtr->data < node->data;
However, I would suggest refactoring to have a full separate class for Node; you can put the operator overload in that class.
You pass node as reference so you should use node.data
Remove also the keyword typedef because it makes you only define the type and your list definitively needs a pointer to the first node !
Then you have to update your return to:
return this->nodePtr->data < node.data;
I'm making a B inary S earch T ree (BST for short) and I've run into a problem that I can't figure out.
I shall try and reduce the amount of code but it still may require quite a bit I'm afraid.
Nodes:
template <typename Type>
class BSTNode { // Binary Search Tree nodes
private:
int key; // we search by key, no matter what type of data we have
Type data;
BSTNode *left;
BSTNode *right;
public:
BSTNode (int, Type);
bool add (int, Type);
Type search (int);
BSTNode<Type> *remove (int, BSTNode*);
BSTNode<Type> *minNode (int);
};
Root:
template <typename Type>
class BST { // The binary search tree containing nodes
private:
BSTNode<Type> *root; // Has reference to root node
public:
BST ();
bool add (int, Type);
Type search (int);
bool remove (int);
};
I don't know how much code to give since I don't want to exaggerate, if you need more, say so please.
I do both do recursive search and remove
template<typename Type>
BSTNode<Type> *BSTNode<Type>::remove(int removeKey, BSTNode *parent) {
// Here I try to remove nodes
// Depending on the number of children a node has, I remove in different ways
// The error occurs at removing a node with 2 children
// here I look for smallest node greater than current node, replace current node, delete node I replaced WITH
if (this->left != NULL && this->right != NULL){
int *auxKey = &key;
this = this->right->minNode(auxKey); // replace
return this->right->remove(this->key, this); // remove old node
}
}
Here is minNode:
template<typename Type>
Type *BSTNode<Type>::minNode (int oldKey) {
if (this->left == NULL) {
//oldKey = this->key;
return this->data;
} else
return left->minNode();
}
This is where the error occurs:
this = right->minNode(auxKey);
This causes a chain of errors, but I think the main error is:
error: invalid conversion from 'int*' to 'int' [-fpermissive]
I'm guessing it's something simple I've overlooked, but I just can't find it, have been trying for quite some time.
EDIT: Decided for now to simply pass key to minNode() and ignore oldKey and auxKey, modified minNode to return pointer.
New Error, same place
lvalue required as left operand
Your minNode function takes in an int value representing the old key, but you're passing an int* into it in the remove function (specifically, auxKey). Try passing in the value of the old key, not a pointer to it. Alternatively, if you want to update the in parameter to hold the correct value (you seem to be trying to do this), change the parameter to a reference parameter.
Hope this helps!