Very strange errors while using cout in module file - c++

Sorry, I couldn't make an MRE, the error doesn't happen in the cut code, but I will cut the code as much as possible.
main.cpp
#include <iostream>
#include "Functions.h"
using namespace std;
import TNode;
//USE C++20
int main()
{
string line;
cout << "Enter line:\n";
getline(cin, line);
TNode<char> head = stringToBinaryTree(line);
line;
}
Functions.h
#pragma once
#include <string>
using namespace std;
import TNode;
TNode<char> stringToBinaryTree(string s);
Functions.cpp
#include "Functions.h"
using namespace std;
TNode<char> stringToBinaryTree(string s) {
if (s.size() == 0) return TNode<char>();
TNode<char> result(s[0]);
for (size_t i = 1; i < s.length(); i++)
{
result.addChildren(s[i]);
}
return result;
}
TNode.ixx (cut)
module;
#include <iostream>
export module TNode;
export{
template <class T> class TNode;
}
using namespace std;
template <class T>
class TNode {
T value;
TNode<T>* leftChildren;
TNode<T>* rightChildren;
TNode<T>* Parent;
public:
TNode();
TNode(const T value);
TNode(TNode<T>& parent, const T value);
TNode(const TNode<T>& copyTree);
TNode<T>& operator=(const TNode<T>& source);
TNode<T>* addChildren(T value);
TNode<T>* left() const;
TNode<T>* right() const;
TNode<T>* parent() const;
T getValue() const;
void setValue(T value);
};
//then only the used methods and functions
template <class T> TNode<T>::TNode(TNode<T>& parentNode, const T value) {
this->value = value;
leftChildren = nullptr;
rightChildren = nullptr;
Parent = nullptr;
if (parentNode.getValue() >= value) {
if (parentNode.right() != nullptr) TNode(*parentNode.right(), value);
else {
parentNode.rightChildren = this;
Parent = &parentNode;
}
}
else {
if (parentNode.left() != nullptr) TNode(*parentNode.left(), value);
else {
parentNode.leftChildren = this;
Parent = &parentNode;
}
}
}
template <class T> TNode<T>* TNode<T>::addChildren(T value) {
TNode<T>* children = new TNode<T>(*this, value);
return children;
}
template <class T> void recursionCopy(TNode<T>* dest, const TNode<T>* source) {
dest->addChildren(source->getValue());
//cout << "Added " << source->getValue() << "to destination"; //if uncomment this happens error C2995 and C2572
//if (dest->parent()) cout << " with parrent " << dest->parent() << "\n"; //but if uncomment this while still have prev line uncommented its LNK2005 and LNK1169 errors now
//else cout << "\n";
if (source->left()) {
//cout << "Goind to left with value " << source->left()->getValue() << "\n";
recursionCopy(dest, source->left());
}
if (source->right()) {
//cout << "Goind to right with value " << source->right()->getValue() << "\n";
recursionCopy(dest, source->right());
}
}
template <class T> TNode<T>::TNode(const TNode<T>& copyTree) {
value = copyTree.value;
recursionCopy(this, &copyTree);
}
template <class T> T TNode<T>::getValue() const {
return value;
}
template <class T> TNode<T>* TNode<T>::parent() const {
return Parent;
}
The problem happens in the recursionCopy() function.
When I don't uncomment the cout code, there are no compilation or link errors.
When I uncomment the first line where I used getValue(), the compiler is getting MAD and saying the operator!= template is already defined. Why? I am not defining or using operator!=, but it gives me this error from the <iosfwd> file.
But the interesting part comes when I uncomment the second line with parent(), it causes linker errors with 8 functions, but in Functions.obj for some reason. Here one of the linker errors:
"public: void __thiscall std::basic_ostream<char,struct std::char_traits<char> >::_Osfx(void)" (?_Osfx#?$basic_ostream#DU?$char_traits#D#std###std##QAEXXZ)" already defined in Functions.obj

Related

How to implement a lambda within a depth first function

I'm programming a family tree, and I was instructed to use lambda in the depth first search. I've tried to implement it, and I understand the basics of lambdas. I can't for the life of me understand how to make it work with the instructions I was getting from the teacher. Here is how I've tried to apply the code.
void depthFirst(const std::function<void(Node* )>& node) {
auto traverse = [](Node* node) {
node(this);
for( auto search: Person) {
search->depthFirst(node);
}
};
}
template<typename T>
class Node {
public:
explicit Node(const T& data, Node* parent = nullptr) : data_(data), parent_(parent) {}
explicit Node(T data): data_(std::move(data)) {}
virtual ~Node() = default;
T getData() const {
return data_;
}
void setData(T data) {
data_ = data;
}
Node *getParent() const {
return parent_;
}
void setParent(Node *parent) {
parent_ = parent;
}
bool leftExists() {
return this->left_ != nullptr;
}
void setLeft(const std::unique_ptr<Node> &left) {
left_ = left;
}
const std::unique_ptr<Node> &getLeft() const {
return left_;
}
bool rightExists() {
return this->right_ != nullptr;
}
const std::unique_ptr<Node> &getRight() const {
return right_;
}
void setRight(const std::unique_ptr<Node> &right) {
right_ = right;
}
private:
T data_; // node's data value with use of template
Node *parent_; // pointer to point at the parent node
std::unique_ptr<Node> left_;
std::unique_ptr<Node> right_;
};
template<typename T>
class Person {
public:
Person();
Person(std::string firstName, std::string lastName, int age, std::string gender, bool alive);
// setters
void setFirstName(const std::string &firstName);
void setLastName(const std::string &lastName);
void setGender(const std::string &gender);
bool isAlive() const;
void setAlive(bool alive);
void setAge(int age);
void setPerson();
// getters
const std::string& getFirstName() const;
const std::string& getLastName() const;
const std::string& getGender() const;
int getAge() const;
bool getAlive() const;
//operators
void displayPerson()const; // for testing atm
void setPerson(const Person& Person);
private:
std::string firstName_;
std::string lastName_;
int age_{};
std::string gender_;
bool alive_ = true;
};
// Functions that sets the data for the Person --->
template<typename T>
void Person<T>::setFirstName(const std::string &firstName) {
firstName_ = firstName;
}
template<typename T>
void Person<T>::setLastName(const std::string &lastName) {
lastName_ = lastName;
}
template<typename T>
void Person<T>::setGender(const std::string &gender) {
gender_ = gender;
}
template<typename T>
bool Person<T>::isAlive() const {
return alive_;
}
template<typename T>
void Person<T>::setAge(int age) {
age_ = age;
}
template<typename T>
void Person<T>::setAlive(bool alive) {
alive_ = alive;
}
// This is the default constructor, overload constructor and destructor for the person class --->
template<typename T>
Person<T>::Person(std::string firstName, std::string lastName, int age, std::string gender, bool alive) :
firstName_(std::move(firstName)), lastName_(std::move(lastName)), age_(age), gender_(std::move(gender)), alive_(alive) {}
template<typename T>
Person<T>::Person() {
}
// Functions that gets the data for the Person --->
template<typename T>
int Person<T>::getAge() const {
return 0;
}
template<typename T>
const std::string &Person<T>::getFirstName() const {
return this->firstName_;
}
template<typename T>
const std::string &Person<T>::getLastName() const
{
return this->lastName_;
}
template<typename T>
const std::string &Person<T>::getGender() const
{
return this->gender_;
}
template<typename T>
bool Person<T>::getAlive() const {
return false;
}
template<typename T>
class FamilyTree
{
public:
FamilyTree();
explicit FamilyTree(Node<T>* root); // Create new tree
FamilyTree(T data):
/*
void addNewPerson();
void addFather();
void addMother();
*/
void addNode(T data);
bool isEmpty();
private:
Node<T> *root_;
void addNode(Node<T>* root, T data);
};
template<typename T>
FamilyTree<T>::FamilyTree(Node<T> *root) {
this->root_ = root;
}
template<typename T>
bool FamilyTree<T>::isEmpty() {
return this->root_ == nullptr;
}
template<typename T>
FamilyTree<T>::FamilyTree() {
this->root_ = nullptr;
}
template<typename T>
void FamilyTree<T>::addNode(T data) {
if(root_ == nullptr)
root_ = std::make_unique(Node<T>(data));
else
addNode(root_, data);
}
//main
//just for test
void Person::displayPerson() const {
std::cout << "First Name: " << this->getFirstName() << std::endl;
std::cout << "Last Name: " << this->getLastName() << std::endl;
std::cout << "Age: " << this->getAge() << std::endl;
std::cout << "Gender: " << this->getGender() << std::endl;
std::cout << "Alive: " << this->getAlive() << std::endl << std::endl;
}
//main
int main(){
// Node test
Node node;
Node* setLeft(reinterpret_cast<Node *>(1));
Node* setRight(reinterpret_cast<Node *>(2));
std::cout << node.getData() << std::endl;
std::cout << node.getLeft() << std::endl;
std::cout << node.getRight() << std::endl;
//Person test
Person p0, p1("Robert", "Dane", 37, "Male", 1), p2("John", "Doe", 35, "Female", 1);
p0.displayPerson();
p1.displayPerson();
p2.displayPerson();
// FT test
return 0;
}
void ignoreLine() // inspiration from here: https://stackoverflow.com/questions/11523569/how-can-i-avoid-char-input-for-an-int-variable
{
std::cin.clear();
std::cin.ignore(INT_MAX, '\n');
}
void showMainMenu() // hold the output for the main menu
{
std::cout << "Welcome" << std::endl;
std::cout << "Please enter a number for your choice below:\n" << std::endl;
std::cout << "(1) Add new person to tree" << std::endl;
std::cout << "(2) Show information for a person" << std::endl;
std::cout << "(3) Print complete family-tree" << std::endl;
std::cout << "(4) Used for testing new choices" << std::endl;
std::cout << "(0) Quit" << std::endl;
std::cout << "\nYour choice: " << std::endl;
}
int main()
{
familyTree fT; // used to access/init. familytree class.
bool exit = true;
int option;
while (exit)
{
showMainMenu();
std::cin >> option;
while (std::cin.fail())
{
ignoreLine();
std::cout << "\nOnly a number between 0 and 10 is allowed: ";
std::cin >> option;
}
switch (option)
{
case 1:
fT.addNewPerson();
break;
case 2:
std::cout << "Enter name of person to show information: ";
int temp;
std::cin >> temp;
fT.show(fT.search(temp));
break;
case 3:
fT.printInOrder(fT.root, 0);
break;
case 4:
/* n/a */
break;
case 0:
exit = false;
break;
default: ;
}
std::cout << "\nPress enter to continue.." << std::endl;
ignoreLine();
}
return 0;
Old code that worked:
person *familyTree::traverseLeft(person *ptr, const std::string& person)
{
ptr = ptr->left;
while (ptr != nullptr)
{
if ((ptr->firstName) == person) {
return ptr;
}
else if (traverseRight(ptr, person) != nullptr)
{
return traverseRight(ptr, person);
}
else
{
ptr = ptr->left;
}
}
return nullptr;
}
person *familyTree::traverseRight(person *ptr, const std::string& person)
{
ptr = ptr->right;
while (ptr != nullptr)
{
if ((ptr->firstName) == person)
{
return ptr;
}
else if (traverseLeft(ptr, person) != nullptr)
{
return traverseLeft(ptr, person);
}
else
ptr = ptr->right;
}
return nullptr;
edit: The teacher told me that node(this); was supposed to point to the current node being searched. I may not have the most pedagogical correct teacher. But it is supposed to search the binary tree depth first, node for node. There is no use of vector or indexes, as I was told it was not needed. There is a class node and a class person that is implemented in to the node. If there is a better way of traversing a tree than this, feel free to let me know.
edited to add Person and Node.
edited to show old code that we got told to burn. I only got the instructions on lambda in person, but in short, was told to create lambda to use on a current node within a void function search, then go right, then go left. It could be reused in delete and other functions.
edited to add last of all code. Should I just go back to the old code (but less OOP) that I know compile and works? I got so much bad reviews on the old one that my group decided to start a new. But right now it's just a mess. (Keep in mind that the "new" code now is on different header files, so it might be more messy in regards to the console and main)
Is there a reason why you direct initialize your private variables in class Person as rvalues (ie. std::move?) ? std::string can bind permitted rvalues as long as they're const.
For instance the code below:
template<typename T>
Person<T>::Person(std::string firstName, std::string lastName, int age, std::string gender, bool alive) \
: firstName_(std::move(firstName)), lastName_(std::move(lastName)), age_(age), gender_(std::move(gender)), alive_(alive) {}
Could be:
template <typename T>
Person<T>::Person(std::string firstName, std::string lastName, int age, std::string gender, bool alive) \
: firstName_{firstName}, lastName_{lastName}, age_{age}, gender_{gender}, alive_{alive} {}
Making the the members in Person rvalues would be preparing them for a move, which it does not look like you're doing earlier in the code.
template <typename T>
void Person<T>::setFirstName(const std::string &firstName)
{
firstName_ = firstName;
}
The values are being passed as lvalue references in the function parameters of Person, which you are changing to rvalues in the constructor of said class. There is no need to do this. They are not meant to be temporary values. The use of {} instead of () eliminates the chance of implicit conversion (narrowing) on part of the members.
You're thinking inside out or upside down - you should pass a lambda (or another function) to this function, and this should apply that function in a depth-first manner.
You also need a helper function that takes a Node* that indicates the current node.
A very simple example, with a preorder traversal:
private:
void traverse(const std::function<void(Node*)>& action, Node* current)
{
if (current != nullptr)
{
action(current);
traverse(action, current->getLeft());
traverse(action, current->getRight());
}
}
public:
void traverse(const std::function<void(Node*)>& action)
{
traverse(action, root_);
}
And you are supposed to use it something like this:
FamilyTree tree = ... whatever ...;
auto process = [](const Node* p) { ... print p ... };
// This will now print in preorder.
tree.traverse(process);

Problem with throw exceptions when stack are empty ..... Queue / stack implementation

I need to throw an exception when both stacks are empty but i dont know how I should write it.
I have to implement a queue with 2 stacks!
this is main
#include "QueueFromStacks.h"
int main()
{
/* THIS IS JUST TO SHOW YOU HOW #include <stack> WORKS
stack<int> st1;
stack<int> st2;
cout << "Size before push:" << st2.size() << "\n";
st2.push(2);
st2.push(5);
cout << "Size after two pushes:" << st2.size() << "\n";
cout << st2.top() << "\n";
st2.pop();
cout << "Size of st2 after one pop:" << st2.size() << "\n";
st1.push(st2.top());
st2.pop();
cout << "Size of st1:" <<st1.size()<< " Size of st2:"<< st2.size();
*/
QueueFromStacks<int> qfs;
qfs.QueueFromStacks();
qfs.enqueue(1);
qfs.enqueue(2);
qfs.enqueue(3);
qfs.dequeue();
cout << "Queue Front : " << (qfs.front())<< endl;
// You have to implement QueuefromStack
// The logic of the queue remains the same(FIFO) but you have to use the two stacks to store your elements
// In the main program create a queuefromstack object and use your implemented methods to clearly show us what u did
return 0;
}
HEADER FILE
#ifndef QUEUEFROMSTACKS_H_
#define QUEUEFROMSTACKS_H_
#include <iostream>
#include <stack>
#include <string>
using namespace std;
class QueueEmptyException{
public:
QueueEmptyException();
~QueueEmptyException();
string getMessage() { return "Queue is empty"; }
};
template <typename E>
class QueueFromStacks
{
public:
QueueFromStacks();
~QueueFromStacks();
int size() const;
bool empty() const;
const E& front() const throw(QueueEmptyException);
void enqueue (const E& e);
void dequeue() throw(QueueEmptyException);
private:
stack<E> st1;
stack<E> st2;
int numElements;
};
#endif /* QUEUEFROMSTACKS_H_ */
IMPLEMENTATION
#include "QueueFromStacks.h"
template <typename E>
QueueFromStacks<E>::QueueFromStacks()
{
numElements = 0;
}
template <typename E>
QueueFromStacks<E>::~QueueFromStacks()
{
// TODO Auto-generated destructor stub
}
template <typename E>
int QueueFromStacks<E>::size() const
{
return numElements;
}
template <typename E>
bool QueueFromStacks<E>::empty() const
{
return (size() == 0);
}
template <typename E>
const E& QueueFromStacks<E>::front() const
throw(QueueEmptyException)
{
return st2.top(); // don't forget to check for empty and throw exception if it is empty.
}
template <typename E>
void QueueFromStacks<E>::enqueue (const E& e)
{
st2.push(e);
numElements++;
}
template <typename E>
void QueueFromStacks<E>::dequeue()
throw(QueueEmptyException)
{
**// if both stacks are empty // here i dont know what should i put as a throw condition
if (st1.empty() && st2.empty())
{
throw;
}**
// if the second stack is empty, move elements from the first stack to it
if (st2.empty())
{
while (!st1.empty())
{
st2.push(st1.top());
st1.pop();
}
// or make a call to swap(s1, s2)
}
// return the top item from the second stack
int top = st2.top();
st2.pop();
numElements--;
}
You need to change this:
void QueueFromStacks<E>::enqueue (const E& e)
{
st2.push(e);
numElements++;
}
to this:
void QueueFromStacks<E>::enqueue (const E& e)
{
st1.push(e);
numElements++;
}

BST inorder method referencing vector showing error: declaration is incompatible

I am a beginner at c++ and I am coding a program that stores data into a BST template class the being another class called log_t that stores the variables, I am trying to use the inorder method from the BST class to reference a vector from main, to input the values into and be able to use it in the main class
my main class
int main(int argc, char* argv[])
{
BST<log_t> l;
string infilename = "";
string filePath = "data\\";
string files[1] = {
filePath + "MetData-31-3a.csv"
//filePath + "Jan20071toDec31abcdefghijklmnopq",
//filePath + "Jan20081toDec31abcdefghijklmnopq",
//filePath + "MetData_Jan01-2010-Jan01-2011-ALL"
};
/// checks if file can open
for (int i = 0; i < 1; i++) {
infilename = files[i];
ifstream infile(infilename);
if (!infile.is_open())
{
cout << "unable to read file" << files[i] << endl;
}
else
{
cout << "reading file" << files[i] << endl;
}
/* parse sensor data csv file */
string tmp;
getline(infile, tmp); // skip the first line
while (getline(infile, tmp))
{
// if successfully parsed then append into vector
log_t logline;
if (ParseLog(tmp, logline))
l.insert(logline);
}
}
cout << " end with reading file" << endl;
/* aggregate/filter logs */
Vector<log_t> vec;
l.inorder(vec);
/* prompt menu */
// this array stores all the menu option callback functions
void(*funs[])(const Vector<log_t> & vec) = { NULL, &option1, &option2, &option3, &option4, &option5,&option6 };
// keep printing menu in loop
while (true)
{
// prompt menu and ask user to select option
int choice = PromptMenu();
// check validity of choice
if (choice < 1 || choice > 6)
{
cout << "invalid choice" << endl;
}
else
{
cout << endl;
// call menu option handler
(funs[choice])(vec);
}
}
system("pause");
return -1;
}
my BST class
#include <string>
#include <iostream>
#include <stream>
#include <iomanip>
#include <stream>
#include "date.h"
#include "times.h"
#include "log_t.h"
#include "Vector.h"
using namespace std;
template <class T>
class BST {
private:
struct Node {
T num;
Node* left;
Node* right;
};
Node* root = NULL;
Node* insert(Node* node, T x);
Node* newnode(T num);
void removeprivate(T num, Node* parent);
T findsmallestprivate(Node* ptr);
void inorderprivate(Node* ptr, void (BST<T>::* FT)(T&), Vector<log_t>const& log);
void postorderprivate(Node* ptr, void (BST<T>::* FT)(T&));
void preorderprivate(Node* ptr, void (BST<T>::* FT)(T&));
//void inorderprivate(Node* ptr);
//void postorderprivate(Node* ptr);
//void preorderprivate(Node* ptr);
void removematch(Node* parent, Node* match, bool left);
public:
void insert(T num);
void remove(T num);
void removerootmatch();
T findsmallest();
void inorder(Vector<log_t>const& log);
void postorder();
void preorder();
void print(T& p) { cout << p << " "; };
};
template <class T>
void BST<T>::inorder(Vector<log_t>const& log) {
inorderprivate(root,print,log);
}
template <class T>
void BST<T>::inorderprivate(Node* ptr, void (BST<T>::* FT)(T&), Vector<log_t>const&
log) {
if (root != NULL)
{
if (ptr->left != NULL)
{
inorderprivate(ptr->left, FT);
}
(this->*FT)(log);
log.Append( ptr->num);
if (ptr->right != NULL)
{
inorderprivate(ptr->right, FT);
}
}
else
{
cout << "tree is empty";
}
}
my log_t class the T type
#pragma once
#ifndef LOG_T_H
#define LOG_T_H
#include <iostream>
#include <stream>
#include <string>
#include <algorithm>
#include <iomanip>
#include <stream>
#include "date.h"
#include "times.h"
#include "BST.h"
class log_t
{
public:
log_t();
log_t(log_t& log);
float gettemp();
float getwind();
float getsolar();
void setwind(float wind);
void setsolar(float rad);
void settemp(float temp);
Date date;
Times time;
private:
float wind_speed;
float solar_radiation;
float air_temperature;
};
log_t::log_t()
{
wind_speed = 0;
solar_radiation = 0;
air_temperature = 0;
}
log_t::log_t(log_t& log) {
wind_speed = log.wind_speed;
solar_radiation = log.solar_radiation;
air_temperature = log.air_temperature;
date.SetDate(log.date.GetDay(), log.date.GetMonth(), log.date.GetYear());
time.SetHour(log.time.GetHour());
time.SetMinute(log.time.GetMinute());
}
float log_t:: gettemp()
{
return air_temperature;
}
float log_t::getwind() {
return wind_speed;
}
float log_t::getsolar() {
return solar_radiation;
}
void log_t::setwind(float wind)
{
wind_speed = wind;
}
void log_t::setsolar(float rad)
{
solar_radiation = rad;
}
void log_t::settemp(float temp)
{
air_temperature = temp;
}
#endif // LOG_T_H
my vector class
#pragma once
#ifndef VECTOR_H
#define VECTOR_H
#include <iostream>
#include <stream>
#include <string>
template <class T>
class Vector
{
public:
Vector();
Vector(int capacity);
Vector(const Vector& vec);
Vector& operator=(const Vector& vec);
~Vector();
int GetSize() const;
void Expand();
T& GetLast();
void Append(const T& val);
T& operator[](int idx);
const T& operator[](int idx) const;
private:
T* elems;
int capacity;/** < int capacity, stores the size of the array */
int count;
void CopyFrom(const Vector& vec);
};
template <class T>
inline Vector<T>::Vector() : elems(nullptr), capacity(0), count(0)
{
}
template <class T>
inline Vector<T>::Vector(int capacity)
: elems(new T[capacity]()), capacity(capacity), count(0)
{
}
template <class T>
inline Vector<T>::Vector(const Vector& vec)
{
CopyFrom(vec);
}
template <class T>
inline Vector<T>& Vector<T>::operator=(const Vector& vec)
{
if (elems)
delete[] elems;
CopyFrom(vec);
return *this;
}
template <class T>
inline Vector<T>::~Vector()
{
if (elems)
delete[] elems;
}
template <class T>
inline int Vector<T>::GetSize() const
{
return count;
}
template <class T>
inline void Vector<T>::Expand()
{
++count;
if (count > capacity)
if (capacity)
capacity *= 2;
else
capacity = 4;
T* tmp = new T[capacity]();
for (int i = 0; i < count - 1; ++i)
tmp[i] = elems[I];
if (elems)
delete[] elems;
elems = tmp;
}
template <class T>
inline T& Vector<T>::GetLast()
{
return elems[count - 1];
}
template <class T>
inline void Vector<T>::Append(const T& oval)
{
Expand();
GetLast() = val;
}
template <class T>
inline T& Vector<T>::operator[](int idx)
{
return elems[idx];
}
template <class T>
inline const T& Vector<T>::operator[](int idx) const
{
return elems[idx];
}
template <class T>
inline void Vector<T>::CopyFrom(const Vector& vec)
{
elems = new T[vec.capacity]();
capacity = vec.capacity;
count = vec.count;
for (int i = 0; i < count; ++i)
elems[i] = vec.elems[i];
}
#endif //VECTOR_H
the errors that keep showing up are
Severity Code Description Project File Line Suppression State
Error (active) E0147 declaration is incompatible with "void BST::inorder(const Vector<> &log)" (declared at line 241 of "C:\Users\Frances\Documents\A2\A2\BST.h") A2 C:\Users\Frances\Documents\A2\A2\BST.h 241
Severity Code Description Project File Line Suppression State
Error C2065 'log_t': undeclared identifier A2 C:\Users\Frances\Documents\A2\A2\BST.h 33
Severity Code Description Project File Line Suppression State
Error C2923 'Vector': 'log_t' is not a valid template type argument for parameter 'T' A2 C:\Users\Frances\Documents\A2\A2\BST.h 33
could someone help me figure out what it is that's causing this or what I am doing wrong, I have been trying to find an answer for hours and haven't been successful thank you

Class Template and Reference Return Type

Long-time reader, first-time poster!
A few comments before I begin: I'm not looking for anyone to do my work for me, I just need a little guidance. Also, I've done a decent amount of googling, and I haven't been able to find any solutions yet.
I have a class assignment that involves creating a template for the following class:
class SimpleStack
{
public:
SimpleStack();
SimpleStack& push(int value);
int pop();
private:
static const int MAX_SIZE = 100;
int items[MAX_SIZE];
int top;
};
SimpleStack::SimpleStack() : top(-1)
{}
SimpleStack& SimpleStack::push(int value)
{
items[++top] = value;
return *this;
}
int SimpleStack::pop()
{
return items[top--];
}
Everything seems to work except SimpleStack& push(int value):
template <class T>
class SimpleStack
{
public:
SimpleStack();
SimpleStack& push(T value);
T pop();
private:
static const int MAX_SIZE = 100;
T items[MAX_SIZE];
int top;
};
template <class T>
SimpleStack<T>::SimpleStack() : top(-1)
{}
template <class T>
SimpleStack& SimpleStack<T>::push(T value)
{
items[++top] = value;
return *this;
}
template <class T>
T SimpleStack<T>::pop()
{
return items[top--];
}
I keep getting the following errors on the definition of SimpleStack& push(int value): "use of class template requires template argument list," and "unable to match function definition to an existing declaration."
Here is main if it helps:
#include <iostream>
#include <iomanip>
#include <string>
#include "SimpleStack.h"
using namespace std;
int main()
{
const int NUM_STACK_VALUES = 5;
SimpleStack<int> intStack;
SimpleStack<string> strStack;
SimpleStack<char> charStack;
// Store different data values
for (int i = 0; i < NUM_STACK_VALUES; ++i)
{
intStack.push(i);
charStack.push((char)(i + 65));
}
strStack.push("a").push("b").push("c").push("d").push("e");
// Display all values
for (int i = 0; i < NUM_STACK_VALUES; i++)
cout << setw(3) << intStack.pop();
cout << endl;
for (int i = 0; i < NUM_STACK_VALUES; i++)
cout << setw(3) << charStack.pop();
cout << endl;
for (int i = 0; i < NUM_STACK_VALUES; i++)
cout << setw(3) << strStack.pop();
cout << endl;
return 0;
}
Sorry for the excessive code pasting!
Make it
template <class T>
SimpleStack<T>& SimpleStack<T>::push(T value) {...}

Something weird with operator overloading (C++)

###MyClass.h###
#ifndef _MyClass
#define _MyClass
#include <string>
using namespace std;
class MyClass
{
public:
MyClass(const string name, const string text);
void display(ostream & out) const;
MyClass & operator = (const MyClass & m);
int compare(const MyClass & right) const;
private:
string _name;
string _text;
};
bool operator < (const MyClass & left, const MyClass & right);
ostream & operator << (ostream & out, const MyClass & mc);
#endif
###Node.h###
#include <string>
#include "MyClass.h"
using namespace std;
typedef MyClass * DataType;
class Node
{
private:
DataType item; // data
Node * lchild; // left child pointer
Node * rchild; // right child pointer
public:
Node(DataType Item);
DataType getItem() const;
void setItem(const DataType & data);
Node* getLChild() const;
void setLChild(Node * p);
Node* getRChild() const;
void setRChild(Node * p);
virtual ~Node();
};
###BST.h###
#include "Node.h"
using namespace std;
class BST
{
private:
Node * root;
bool Search(const DataType item, Node * r) const;
void Insert (DataType item, Node * ptr);
void Destructor(const Node * r);
public:
BST();
bool IsEmpty() const;
void Insert(const DataType item);
bool Search(const DataType item) const;
virtual ~BST();
};
###MyClass.cpp###
#include <iostream>
#include "MyClass.h"
using namespace std;
MyClass::MyClass(const string name, const string text)
{
_name = name;
_text = text;
}
void MyClass::display(ostream & out) const
{
out << "Name: " << _name << endl;
out << "Text: " << _text << endl;
}
MyClass & MyClass::operator = (const MyClass & m)
{
if (this == & m)
return *this;
_name = m._name;
_text = m._text;
return *this;
}
int MyClass::compare(const MyClass & right) const
{
return _name.compare(right._name);
}
bool operator < (const MyClass & left, const MyClass & right)
{
return left.compare(right) > 0;
}
ostream & operator << (ostream & out, const MyClass & mc)
{
mc.display(out);
return out;
}
###Node.cpp###
#include "Node.h"
Node::Node(DataType Item):item(Item)
{
lchild = 0;
rchild = 0;
}
DataType Node::getItem() const
{
DataType anItem = item;
return anItem;
}
void Node::setItem( const DataType & data)
{
item = data;
}
Node* Node::getLChild() const
{
Node * p = lchild;
return p;
}
void Node::setLChild(Node * p)
{
lchild = p;
}
Node* Node::getRChild() const
{
Node * p = rchild;
return p;
}
void Node::setRChild(Node * p)
{
rchild = p;
}
Node::~Node()
{
}
###BST.cpp###
#include <iostream>
#include "BST.h"
using namespace std;
bool BST::Search(const DataType item) const
{
return Search(item, root);
}
bool BST::Search(const DataType item, Node * r) const
{
if(r != 0)
{
if (item == r->getItem())
return true;
else
{
if (item < r->getItem())
return Search(item, r->getLChild());
else
return Search(item, r->getRChild());
}
}
else
return false;
}
BST::BST()
{
root = 0;
}
bool BST::IsEmpty() const
{
return (root == 0);
}
void BST::Insert(const DataType item)
{
if(root == 0)
root = new Node(item);
else
Insert(item, root);
}
void BST::Insert(DataType item, Node * ptr)
{
if (item < ptr->getItem())
{
if (ptr->getLChild() == 0)
ptr->setLChild(new Node(item));
else
Insert(item, ptr->getLChild());
}
else
{
if (ptr->getRChild() == 0)
ptr->setRChild(new Node(item));
else
Insert(item, ptr->getRChild());
}
}
void BST::Destructor(const Node * r)
{
if(r!=0)
{
Destructor( r->getLChild());
Destructor( r->getRChild());
delete r;
}
}
BST::~BST()
{
Destructor(root);
}
###main.cpp###
#include <iostream>
#include "MyClass.h"
#include "BST.h"
using namespace std;
void main()
{
MyClass * mc1 = new MyClass("Tree","This is a tree");
MyClass * mc2 = new MyClass("Book","This is a book");
MyClass * mc3 = new MyClass("Zoo","This is a zoo");
BST * tree = new BST();
tree->Insert(mc1);
tree->Insert(mc2);
tree->Insert(mc3);
cout << boolalpha << ("Book" < "Tree") << endl;
cout << (mc2 < mc1) << endl;
cout << (tree->Search(new MyClass("Book",""))) << endl;
}
Result is true false false
I don't know what's wrong with my operator overloading? (mc2 should
less than mc1)
I'm not sure if this is correct for searching a "MyClass" node in a BST?
and the result is "not found"....I traced it into "BST.cpp",
and found that the problem also occurs at " if (item < r->getItem()) "
Can anyone help me or give me a hint....thank you so much!
Here you are just comparing pointers, i.e memory addresses:
cout << (mc2 < mc1) << endl;
To compare the objects, you need to dereference the pointers:
cout << ((*mc2) < (*mc1)) << endl;
In your code snippet, there is no reason for mc1, mc2, etc. to be pointers, so you could avoid the problem by creating objects on the stack directly:
MyClass mc1("Tree","This is a tree");
and so on. I would even go further and say that you should only dynamically allocate objects with new if you really are sure you need to and have good reasons not to allocate automatically on the stack. And if you really must use dynamically allocated pointers, have a look at C++ smart pointers.