Using Template Defined Variables in Function Calls in C++ - c++

I have a function that I am passing in a variable for; the variable, however, is a template variable. I do not know the specifics on how I am supposed to create a function with a template parameter. I do not even know if I am asking the correct question, but when I compile the program, I get the following error in the main.cpp file:
line 17 error: no matching function for call to 'BSTree<int>::BSTinsert(TNode<int>&)'
line 49 error note: candidates are: void BSTree<T>::BSTinsert(const T&) [with T = int]
I thought that I was doing everything right, but this is the one error that has hindered me from moving on. Any and all help is welcome and appreciated! (I don't think that the other two files -- treeNode.h and treeNode.cpp -- need to be shown, but I have been wrong before. If they are, lemme know and I will gladly post them. Thank you once again!
main.cpp:
#include <iostream>
#include <string>
#include "BSTree.cpp"
using namespace std;
int main()
{
BSTree<int> bt;
TNode<int> item;
for(int i=0; i<13; i++)
{
cout << "Enter value of item: ";
cin >> item;
bt.BSTinsert(item); //this is the line with the error
}
cout << "Hello world!" << endl;
return 0;
}
BSTree.h:
#ifndef BSTREE_H_INCLUDED
#define BSTREE_H_INCLUDED
#include "treeNode.cpp"
template <typename T>
class BSTree
{
TNode<T> *root;
void insert(TNode<T> * & r, const T & item);
public:
BSTree();
TNode<T>* getRoot();
void BSTinsert(const T & item);
};
#endif // BSTREE_H_INCLUDED
BSTree.cpp:
#include <iostream>
#include <string>
#include "BSTree.h"
template <typename T>
void BSTree<T>::insert(TNode<T> * & r, const T & item)
{
if(r == NULL)
TNode<T> newNode = new TNode<T>(item);
else if(r == item)
return;
else if(r->nodeValue > item)
insert(r->leftChild, item);
else if(r->nodeValue > item && r->leftChild == NULL)
{
TNode<T> newNode = new TNode<T>(item);
r->leftChild = newNode;
newNode->parent = r;
}
else if(r->nodeValue < item)
insert(r->rightChild, item);
else if(r->nodeValue < item && r->rightChild == NULL)
{
TNode<T> newNode = new TNode<T>(item);
r->rightChild = newNode;
newNode->parent = r;
}
}
template <typename T>
BSTree<T>::BSTree()
{
root = NULL;
}
template <typename T>
TNode<T>* BSTree<T>::getRoot()
{
return root;
}
template <typename T>
void BSTree<T>::BSTinsert(const T& item) //this is the line the note is referring to
{
TNode<T> tempRoot = getRoot();
insert(tempRoot, item);
}
treeNode.cpp:
#include <string>
#include <iostream>
#include "treeNode.h"
using namespace std;
template <typename T>
TNode<T>::TNode()
{
parent = NULL;
leftChild = NULL;
rightChild = NULL;
nodeValue = 0;
}
template <typename T>
TNode<T>::TNode(const T&item, TNode<T> *left, TNode<T> *right, TNode<T> *par)
{
parent = par;
leftChild = left;
rightChild = right;
nodeValue = item;
}
template <typename T>
void TNode<T>::printNodeInfo()
{
cout << "Value: " << nodeValue << endl;
if(parent != NULL)
cout << "Parent Value: " << parent << endl;
if(leftChild != NULL)
cout << "Left Child Value: " << leftChild << endl;
if(rightChild != NULL)
cout << "Right Child Value: " << rightChild << endl;
}
treeNode.h:
#ifndef TREENODE_H_INCLUDED
#define TREENODE_H_INCLUDED
template <typename T>
class TNode
{
public:
T nodeValue;
TNode<T> *leftChild, *rightChild, *parent;
TNode();
TNode(const T&item, TNode<T> *left = NULL, TNode<T> *right = NULL, TNode<T> *par = NULL);
void printNodeInfo();
friend std::istream& operator>>( std::istream& i, TNode<T>& item ){return i;}
};
#endif // TREENODE_H_INCLUDED

Does this solve your problem?
int main()
{
BSTree<int> bt;
int item;
for(int i=0; i<13; i++)
{
cout << "Enter value of item: ";
cin >> item;
bt.BSTinsert(item); //this is the line with the error
}
cout << "Hello world!" << endl;
return 0;
}

Related

Implementing a stack using a linked list and class templates

I'm trying to implement a stack using a linked list and class template. I'm not getting any compiler errors but my logic may be wrong, kind of lost. I had a working program in just a single file only using a struct so I had difficulties with translating it over using multiple files and template classes. I will also include my single file cpp below, hopefully it helps. Any help will be greatly appreciated. I have a header.h file, functions.cpp and main. cpp.
Header.h
#define STACK_H
#include <iostream>
using namespace std;
//to implement a stack using linked list
template<class T>
class node{
public:
T data;
node<T>*next;
};
template<class T>
class stack{
private:
node<T> *item;
node<T> *top;
public:
stack(); // constructor
void push( node<T> *); // to insert an item to the stack
void pop(); // to remove an item from the stack
void display(); // to display the stack elements on screen
node<T> *newnode(int );
};
#include "functions.cpp"
#endif
functions.cpp
#include <iostream>
#include "header.h"
#ifndef FUNCTIONS
#define FUNCTIONS
using namespace std;
template<class T>
stack <T> :: stack(){
node<T> *top = NULL;
}
template<class T>
void stack <T> :: push(node<T> * q){
if (top == NULL)
top = q;
else
{
q->next = top;
top = q;
}
}
template<class T>
void stack <T> :: pop(){
if (top == NULL) {
cout << "Stack is empty";
}
else {
cout << "Popped element is " << top->data;
item = top;
top = top->next;
delete(item);
}
}
template<class T>
void stack <T> :: display(){
node<T> *q;
q = top;
if (top == NULL) {
cout << "Stack is empty!!";
}
else {
while (q != NULL)
{
cout << q->data << " ";
q = q->next;
}
}
}
template<class T>
node<T> * stack <T> :: newnode(int x)
{
item = new node<T>;
item->data = x;
item->next = NULL;
return(item);
}
#endif
main.cpp
#include<iostream>
#include "header.h"
using namespace std;
int main()
{
int ch, x;
stack <int> myStack;
node<int> *nptr;
do
{
cout << "\n\n1.Push\n2.Pop\n3.Print Stack\n4.Exit";
cout << "\nPlease enter a function(1-4):";
cin >> ch;
if (ch == 1)
{
cout << "\nEnter data:";
cin >> x;
nptr = myStack.newnode(x);
myStack.push( nptr);
}
else if (ch == 2)
{
myStack.pop();
}
else if (ch == 3)
{
myStack.display();
}
else cout << "\nInvalid Entry";
} while (ch != 4);
return 0;
}
Single file working program
struct nodeType
{
int data;
nodeType *next;
};
nodeType *top = NULL;
nodeType *p;
nodeType* newnode(int x)
{
p = new nodeType;
p->data = x;
p->next = NULL;
return(p);
}
void push(nodeType *q)
{
if (top == NULL)
top = q;
else
{
q->next = top;
top = q;
}
}
void pop() {
if (top == NULL) {
cout << "Stack is empty";
}
else {
cout << "Popped element is " << top->data;
p = top;
top = top->next;
delete(p);
}
}
void printStack()
{
nodeType *q;
q = top;
if (top == NULL) {
cout << "Stack is empty!!";
}
else {
while (q != NULL)
{
cout << q->data << " ";
q = q->next;
}
}
}
int main()
{
int ch, x;
nodeType *nptr;
do
{
cout << "\n\n1.Push\n2.Pop\n3.Print Stack\n4.Exit";
cout << "\nPlease enter a function(1-4):";
cin >> ch;
if (ch == 1)
{
cout << "\nEnter data:";
cin >> x;
nptr = newnode(x);
push(nptr);
}
else if (ch == 2)
{
pop();
}
else if (ch == 3)
{
printStack();
}
else cout << "\nInvalid Entry";
} while (ch != 4);
return 0;
}

why do I have to enter the sentinel value twice to exit the loop?

I am pretty new to c++ . I am learning about link list right now . My program should terminate when I enter 0 but I have to enter the sentinel value ( which is 0 ) twice and how can I not insert the 0 into the list ? Can someone please explain to me what's happening and thanks for your time , I really appreciate it .
this is the output
This is my code .
#include <iostream>
using namespace std;
template <class T>
class List {
private:
struct Node {
T data;
Node *link; };
Node *pHead, *pCurr;
int numItem;
public:
List(); ~List();
int AddToFront();
bool Traverse(T, int &);
void PrintData();
int NumberOfItem();
int Item(int );
};
using namespace std;
template <class T>
List<T>::List() {
numItem = 0; pHead = NULL;
}
template <class T> List<T>::~List() {}
template <class T> int List<T>::AddToFront() {
T item ; Node *pNew = new Node;
cout << "\nEnter Registration No : ";
cin >> item;
pNew->data = item;
pNew->link = pHead;
pHead = pNew;
numItem++;
return item;
}
template <class T> bool List<T>::Traverse(T target, int &loc) {
if (numItem == 0) cout << "List is empty\n";
else {
pCurr = pHead; loc = 0;
while (pCurr->data != target && pCurr->link != NULL) {
pCurr = pCurr->link;
loc++;
}
if (pCurr->data == target) return true;
else return false;
}
}
template <class T>
void List<T>::PrintData() {
pCurr = pHead;
while (pCurr != NULL) {
cout << pCurr->data << " ";
pCurr = pCurr->link;
}
cout << endl;
}
template <class T> int List<T>::NumberOfItem() { return numItem; }
template <class T> int List<T>::Item(int item) { return item; }
template class List<int>;
int main() {
int target, location;
List<int> x;
cout << "\nBasement Parking\n ";
while (x.AddToFront() != 0); {
x.AddToFront();
}
cout << "\nNumber of car(s) parked : " << x.NumberOfItem() - 1;
cout << "\nThe list are : " << endl;
x.PrintData();
cout << "\nEnter the search item : "; cin >> target;
if (x.Traverse(target, location) == true) cout << "Car found at location : " << "location " << location + 1 << endl;
else cout << "Item not found\n\n";
}
The problem is that you call AddToFront twice in the while loop.
The first call you check the return value to see if you should stop looping, the second call you don't use the value.
Here's a small example of what you are currently doing
#include <iostream>
int test() {
int x;
std::cin >> x;
return x;
}
int main() {
while (test() != 0) {
test();
}
return 0;
}
Since you aren't using the return value of AddToFront except to check when to stop adding values you could instead change it to something like this
#include <iostream>
int test() {
int x;
std::cin >> x;
return x;
}
int main() {
while (test() != 0);
return 0;
}
This is a while loop with no body and will call the test function until the return value is zero.
To prevent zero from being inserted into the list you could wrap the lines that insert a value in a if statement
template <class T> int List<T>::AddToFront() {
T item ; Node *pNew = new Node;
cout << "\nEnter Registration No : ";
cin >> item;
if (item != 0) {
pNew->data = item;
pNew->link = pHead;
pHead = pNew;
numItem++;
}
return item;
}

Binary Search Tree Display issue

I have a lab assignment that I have been working on for the last couple of weeks and I am stuck and desperately need help as this will be about 50% of the final project.
The assignment is to create a Binary Search Tree in C++. We have to read in the words from the Declaration of Independence into a Binary Search Tree. I have my search and insert methods "working properly" meaning that they aren't throwing any errors. The problem I am having is displaying the BST to figure out if everything is working properly. The display method should be called by the overloaded operator >> to display the tree.
The errors I keep getting are:
"error C3867: 'BST::display': function call missing
argument list; use '&BST::display' to create a pointer to
member"
and the other one is
"error C2679: binary '<<' : no operator found which takes a right-hand
operand of type 'overloaded-function' (or there is no acceptable
conversion)."
Last time I rebuilt the program it shows "ItelliSense: a pointer to a bound function may only be used to call the function."
#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
template <typename T>
class BST{
private:
struct node {
T data;
struct node* left;
struct node* right;
};
node* root;
public:
BST()
{
root = NULL;
}
bool isEmpty() const { return root == NULL; }
~BST();
template <typename T>
void insert(T d)
{
node* t = new node;
node* parent;
t->data = d;
t->left = NULL;
t->right = NULL;
parent = NULL;
if (isEmpty()) root = t;
else {
node* current;
current = root;
while (current)
{
parent = current;
if (t->data > current->data) current = current->right;
else current = current->left;
}
if (t->data < parent->data)
parent->left = t;
else
parent->right = t;
}
}
template<typename T>
bool search(T d)
{
if (root == NULL)
return false;
else if (d == root->item) {
return true;
}
else if (d < root->item) {
return search(root->left, d);
}
else {
return search(root->right, d);
}
}
template<typename T>
void display(node *p, std::ostream& os)
{
if (p != NULL)
{
if (p->left) display(p->left);
os << " " << p->data << " ";
if (p->right) display(p->right);
}
}
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(os, obj.root);
}
};
int main( )
{
BST<string> s;
ifstream inFile;
string word, tmp;
string filename = "Independence.txt";
ifstream fstr(filename.c_str());
while (inFile >> word) {
s.insert(word);
}
inFile.close();
cout << s << std::endl;
cout << "Search for: ";
cin.ignore(1);
cin >> tmp;
s.search(tmp);
return 0;
};
template<typename T>
void display(node *p)
This takes a parameter with a node pointer.
Then you call it later with:
BST<string> s;
cout << s.display << endl;
But you don't actually pass it any parameters here. The compiler then complains it can't figure out how to call that function. Because that function has a return type of void it can't figure out how to print it as you aren't actually returning anything for cout to print. You will want to fix both these problems before you move on, given that you said it's an assignment I'll leave you to figure out how to do that :).
There seem to be a number of problems with your code. I suspect display and search should not be separately templated - this would actually be a template member function inside a template class and I don't think that's what you intended. Also, the search function refers to node::item, but the declaration of the node type has node::data. Finally, BST::display is written to be a void function taking a node in a way that it could be declared static but your usage is as if you expect it to work like a member function. It doesn't return anything so it certainly can't be passed to iostream::operator<<. Better would be to have display take the iostream as input and then call it as either root->display(cout) or display(cout, root) depending on whether you want it to be a member function or a static function.
you have a couple of concept errors,
the display method returns void so you cannot pass it to cout that expect something to show.
So, the easy change for you will be to add a new method called display_tree like this
void display_tree()
{
display(root);
}
and in your main only call the method
s.display_tree();
not like this
cout << s.display << std::endl; //this is wrong cause this is not even calling a method
another option is to override the << operator, but editing your diplay method like this
template<typename T> void display(node *p, std::ostream& os)
{
if (p != NULL)
{
if (p->left) display(p->left);
os << " " << p->data << " ";
if (p->right) display(p->right);
}
}
and then outside your class
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(obj.root);
}
and call it in your programa like this
cout << s << std::endl;
in order to this to work, the T needs to have the operator << overloaded (which is the case of the string in your case)
try with this instead -- new version compiling
void display(node *p, std::ostream& os) const
{
if (p != NULL)
{
if (p->left) display(p->left,os);
os << " " << p->data << " ";
if (p->right) display(p->right,os);
}
}
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(obj.root,os);
return os;
}
Here is your code compiling and fixed the search
#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
template <typename T>
class BST{
private:
struct node {
T data;
struct node* left;
struct node* right;
};
node* root;
template<typename T> bool search(node* p, T d)
{
if (!p) {
return false;
}
if (d == p->data) {
return true;
}
else if (d < p->data) {
return search(root->left, d);
}
else {
return search(root->right, d);
}
}
public:
BST()
{
root = NULL;
}
bool isEmpty() const { return root == NULL; }
~BST();
template <typename T>
void insert(T d)
{
node* t = new node;
node* parent;
t->data = d;
t->left = NULL;
t->right = NULL;
parent = NULL;
if (isEmpty()) root = t;
else {
node* current;
current = root;
while (current)
{
parent = current;
if (t->data > current->data) current = current->right;
else current = current->left;
}
if (t->data < parent->data)
parent->left = t;
else
parent->right = t;
}
}
template<typename T> bool search(T d)
{
if (root == NULL)
return false;
else if (d == root->data) {
return true;
}
else if (d < root->data) {
return search(root->left, d);
}
else {
return search(root->right, d);
}
}
void display(node *p, std::ostream& os) const
{
if (p != NULL)
{
if (p->left) display(p->left,os);
os << " " << p->data << " ";
if (p->right) display(p->right,os);
}
}
template<typename T> friend std::ostream& operator<<(std::ostream& os, const BST<T>& obj)
{
obj.display(obj.root,os);
return os;
}
};
int main()
{
BST<string> s;
ifstream inFile;
string word, tmp;
string filename = "Independence.txt";
ifstream fstr(filename.c_str());
while (inFile >> word) {
s.insert(word);
}
inFile.close();
cout << s << std::endl;
cout << "Search for: ";
cin.ignore(1);
cin >> tmp;
s.search(tmp);
return 0;
};

C++ - Reverse function in a template class stack implementation

this is my stack implementation using template with a struct type node and a class type stack:
Stack.h
#ifndef STACK_H_
#define STACK_H_
#include <cstdlib>
#include <iostream>
#include <cassert>
using namespace std;
template <class t>
struct node{
t data;
node<t>* next;
};
template <class t>
class stack
{
public:
stack();
~stack();
bool isEmpty(){ return (top_ptr=NULL);};
void push(const t&);
void pop();
t top() const;
void reverse();
void clear();
void print();
private:
node<t>* top_ptr;
};
template <class t>
stack<t>::stack()
{
top_ptr=NULL;
}
template <class t>
stack<t>::~stack()
{
while(top_ptr != NULL) pop();
}
template <class t>
void stack<t>::push(const t& source)
{
node<t>* new_node = new node<t>;
new_node->data = source;
new_node->next = top_ptr;
top_ptr = new_node;
cout << "Inserito!" << endl;
}
template <class t>
void stack<t>::pop()
{
node<t>* remove = top_ptr;
top_ptr = top_ptr->next;
delete remove;
cout << "Rimosso!" << endl;
}
template <class t>
t stack<t>::top() const
{
assert(top_ptr != NULL);
return top_ptr->data;
}
template <class t>
void stack<t>::clear()
{
node<t>* temp;
while(top_ptr != NULL)
{
temp = top_ptr;
top_ptr = top_ptr->next;
delete temp;
}
cout << "Clear completato!" << endl;
}
template <class t>
void stack<t>::reverse()
{
stack<t> new_stack;
while(top_ptr != NULL)
{
new_stack.push(top_ptr->data);
pop();
}
cout << "Reverse completato!" << endl;
}
template <class t>
void stack<t>::print()
{
node<t>* ptr = top_ptr;
while(ptr!=NULL)
{
cout << " " << ptr->data << endl;
ptr = ptr->next;
}
}
#endif /* STACK_H_ */
And this is the main.cpp:
#include "stack.h"
int main()
{
stack<int> stackino;
for(int i = 0; i<10; i++) stackino.push(i);
stackino.pop();
cout << "top(): " << stackino.top() << endl;
stackino.print();
cout << "Invoco clear()" << endl;
stackino.clear();
cout << "Stackino dopo clear():" << endl;
stackino.print();
cout << "Invoco reverse()" << endl;
stackino.reverse();
cout << "Stackino dopo reverse()" << endl;
stackino.print();
cout << "FINE!" << endl;
return 0;
}
The problem is reverse() that causes a crash of the program, I guess "top_ptr = new_stack.top_ptr" is wrong but it makes compile and execute, but crashes. Can someone help me correct this?
I think I understand the issue. Let me know if I am interpreting this wrong.
When you do top_ptr = new_stack.top_ptr, you're putting the temporary stack's top as yours.
The problem is, when that temporary stack gets destructed, it still has the same top_ptr, and deletes all the memory that was associated with it. That leaves your real stack with a bad top_ptr.
I would suggest trying:
top_ptr = new_stack.top_ptr;
new_stack.top_ptr = NULL;
So that it doesn't clear away your stack, and leave you with a bad pointer.
Hope that works?

c++ List class as Student type

I am trying to use a class Student and declare it as a list type. I can pushback but without changing the List.h or Node.h how can I print the data in list2? The given print() function within List..h does not work :(
Node.h
#ifndef NODE_H
#define NODE_H
#include <string>
#include <iostream>
using namespace std;
template <typename T>
class Node {
private:
T data;
Node<T>* next;
public:
Node(T);
virtual ~Node(); // base class destructor must be virtual
template <typename U> friend class List;
};
template <typename T>
Node<T>::Node(T d) {
data = d;
next = NULL;
}
template <typename T>
Node<T>::~Node() {
}
#endif /* STRNODE_H */
List.h
#ifndef LIST_H
#define LIST_H
#include "Node.h"
// Singly linked list
template <typename T>
class List {
private:
Node<T>* head; // pointer to the first node
Node<T>* tail; // pointer to the last node
int count; // number of nodes in the list
public:
class OutOfRangeException{ }; // empty inner class for exception handling
List();
virtual ~List();
void push_back(T item);
void insert(int index, T item);
void remove(int index);
int indexOf(T item);
T get(int position); // OutOfRangeException is generated
bool isEmpty();
int size();
void print();
};
template <typename T>
List<T>::List() {
head = tail = NULL;
count = 0;
}
template <typename T>
List<T>::~List() {
Node<T>* discard;
while (head != 0) {
discard = head;
head = head->next;
delete discard;
}
}
// append an item at the end of the StrList
template <typename T>
void List<T>::push_back(T item) {
try {
Node<T>* newNode = new Node<T>(item);
if (head == 0) {
head = tail = newNode;
} else {
tail->next = newNode;
tail = newNode;
}
++count;
} catch (bad_alloc &e) {
cout << "memory allocation exception: " << e.what() << endl;
exit(1);
}
}
// insert an item at the specified index
template <typename T>
void List<T>::insert(int index, T item) {
try {
if (index < 0 || index > count) // push_back() if index == count
throw OutOfRangeException();
Node<T>* newNode = new Node<T>(item);
if (head == 0) { // empty
head = tail = newNode;
} else if (index == 0) { // at the start
newNode->next = head;
head = newNode;
} else if (index == count) { // at the end
tail->next = newNode;
tail = newNode;
} else { // insert in the middle
Node<T>* prevNode;
Node<T>* currNode = head;
for (int i = 0; i < index; i++) {
prevNode = currNode;
currNode = currNode->next;
}
// insert between 'prevNode' and 'currNode'
prevNode->next = newNode;
newNode->next = currNode;
}
++count;
} catch (bad_alloc &e) {
cout << "memory allocation exception: " << e.what() << endl;
exit(1);
}
}
// is the StrList empty?
template <typename T>
bool List<T>::isEmpty() {
return count == 0;
}
// remove the item at specified index
template <typename T>
void List<T>::remove(int index) {
if (index < 0 || index >= count)
throw OutOfRangeException();
if (index == 0) { // at the start
Node<T>* discard = head;
head = head->next;
delete discard;
} else {
Node<T>* prevNode;
Node<T>* currNode = head;
for (int i = 0; i < index; i++) {
prevNode = currNode;
currNode = currNode->next;
}
// remove 'currNode'
prevNode->next = currNode->next; // bypass
delete currNode;
if (index == count - 1) // last node was removed. Update 'tail'
tail = prevNode;
}
--count;
if (count == 0)
tail = NULL;
}
// retrieve the item at the given position of the StrList. position starts from 0.
// throws OutOfRangeException if invalid position value is given.
template <typename T>
T List<T>::get(int position) {
if (position < 0 || position >= count)
throw OutOfRangeException();
int loc = 0;
Node<T>* curr = head;
while (loc < position) {
++loc;
curr = curr->next;
}
return curr->data;
}
// Requirement:
// != operator of <class T> is used
template <typename T>
int List<T>::indexOf(T item) {
if (head == 0) {
return -1; // not found
} else {
int index = 0;
Node<T>* currNode = head;
while (currNode->data != item && currNode != NULL) {
currNode = currNode->next;
++index;
}
if (currNode == NULL) // not found thru the end
return -1;
else
return index;
}
}
// number of nodes in the StrList
template <typename T>
int List<T>::size() {
return count;
}
// Requirement:
// << operator for <class T> is used.
template <typename T>
void List<T>::print() {
cout << "*** StrList contents ***" << endl;
for (int i = 0; i < count; i++) {
cout << i << ": " << get(i) << endl;
}
}
#endif
Student.h
#include "List.h"
class Student {
private:
string name;
int id;
public:
Student();
Student(string a);
virtual ~Student();
friend ostream& operator<<(ostream &os, const Student& p);
bool operator!=(const Student &p) const;
bool operator==(const Student &p) const;
};
Student::Student() {
}
Student::Student(string a) {
name = a;
}
Student::~Student() {
}
ostream& operator<<(ostream &os, const Student& p) {
return os << p.name;
}
bool Student::operator==(const Student &p) const {
// Compare the values, and return a bool result.
if (name == p.name)
return true;
else
return false;
}
bool Student::operator!=(const Student &p) const {
return !(*this == p);
}
main.cpp
#include <iostream>
using namespace std;
#include "Student.h"
int main() {
cout << "\n*** StrList Test ***" << endl;
List<string> list;
list.push_back("zero");
list.push_back("one");
list.push_back("two");
list.push_back("three");
list.push_back("four");
list.push_back("five");
list.print();
list.insert(1, "inserted at position 1");
list.insert(0, "inserted at position 0");
list.insert(4, "inserted at position 4");
list.print();
cout << "removing at indexes 3, 0" << endl;
list.remove(3);
list.remove(0);
list.print();
list.insert(2, "inserted at position 2");
list.print();
cout << "five is at index " << list.indexOf("five") << endl;
cout << "two is at index " << list.indexOf("two") << endl;
//Test for my Student class implementation
// Student<string> st1; //Create new student Ryan Martin with id of 1
List<Student> list2;
Student stu("Ryan Martin");
list2.push_back(stu);
//list2.print();
//list2.push_back("Ryan");
//list2.PrintStudents(); //Test that the Student class successfully stored and can access
return 0;
}
The << operator must be defined for your Student class. To quote List.h:
// Requirement:
// << operator for <class T> is used.
template <typename T>
void List<T>::print() {
cout << "*** StrList contents ***" << endl;
for (int i = 0; i < count; i++) {
cout << i << ": " << get(i) << endl;
}
}
So in your Student class, you need to implement the operator<<(ostream &out);
Do it as a friend (friends are fun!):
friend std::ostream& operator<< (std::ostream &out, const Student &stu)
{
return out << stu.name << " id: " << stu.id << std::endl;
}
Here is a good reference:
http://www.learncpp.com/cpp-tutorial/93-overloading-the-io-operators/
If I understood you correctly, then you want to define operator<< for your student class, which you can do for example like this:
friend std::ostream & operator<<(std::ostream & os, const Student & s)
{
return os << s.name << " " << s.id << std::endl;
}
Note however that I have not tested this code and I haven't read all the snippets you posted,
so I might have understood you wrongly.
EDIT:
So after trying it out with Visual Studio, the full version of you student class should be like this:
#include "List.h"
class Student {
private:
string name;
int id;
public:
Student();
Student(string a);
virtual ~Student();
friend std::ostream & operator<<(std::ostream & os, const Student & s)
{
return os << s.name << " " << s.id << std::endl;
}
};
Student::Student() {
}
Student::Student(string a) {
name = a;
}
Student::~Student() {
}
Also not that you do not have to make the destructor in Student virtual unless you plan on having it as a base class for other classes.
the print function require an operator << to be defined on your student class and it's not the case
so define how a student will be display by << and it should work!