I was working on templating my assignment here and when I tranfered code that should not have been in my previous cpp file to my header file, this cleared a lot of the issues I was having at I could not template inside the cpp file. Anyway after doing so I was left with two more errors that I am not sure how to fix as they are quite confusing.
LNK2019 unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class fractionType<float> const &)" (??6@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AEAV01@AEBV?$fractionType@M@@@Z) referenced in function main
LNK2019 unresolved external symbol "class std::basic_istream<char,struct std::char_traits<char> > & __cdecl operator>>(class std::basic_istream<char,struct std::char_traits<char> > &,class fractionType<float> &)" (??5@YAAEAV?$basic_istream@DU?$char_traits@D@std@@@std@@AEAV01@AEAV?$fractionType@M@@@Z) referenced in function main
LNK1120 2 unresolved externals
Here is my code
main.cpp
#include <iostream>
#include "fractiontype.h"
using namespace std;
int main() {
//Fraction1 and Fraction2 Objects
fractionType<float> fraction1(2, 3);
fractionType<float> fraction2(0, 0);
//Grab first fraction from user
cout << "Enter a fraction in the form a/b: ";
cin >> fraction1;
//Grab second fraction from user
cout << "Enter another fraction in the form a/b: ";
cin >> fraction2;
//Operators
cout << fraction1 << " + " << fraction2 << " = " << fraction1 + fraction2 << "\n";
cout << fraction1 << " - " << fraction2 << " = " << fraction1 - fraction2 << "\n";
cout << fraction1 << " * " << fraction2 << " = " << fraction1 * fraction2 << "\n";
cout << fraction1 << " / " << fraction2 << " = " << fraction1 / fraction2 << "\n";
//Checking true or false statements
cout << "\n" << fraction1 << " == " << fraction2;
if (fraction1 == fraction2) {
cout << " is true. \n";
}
else {
cout << " is false. \n";
}
cout << fraction1 << " != " << fraction2;
if (fraction1 != fraction2) {
cout << " is true. \n";
}
else {
cout << " is false. \n";
}
cout << fraction1 << " < " << fraction2;
if (fraction1 < fraction2) {
cout << " is true. \n";
}
else {
cout << " is false. \n";
}
cout << fraction1 << " <= " << fraction2;
if (fraction1 <= fraction2) {
cout << " is true. \n";
}
else {
cout << " is false. \n";
}
cout << fraction1 << " > " << fraction2;
if (fraction1 > fraction2) {
cout << " is true. \n";
}
else {
cout << " is false. \n";
}
cout << fraction1 << " >= " << fraction2;
if (fraction1 >= fraction2) {
cout << " is true. \n";
}
else {
cout << " is false. \n";
}
return 0;
}
fractiontype.h
#ifndef H_fraction
#define H_fraction
#include <iostream>
using namespace std;
template <class T>
class fractionType
{
//overload the stream insertion and extraction operators
friend ostream& operator<<(ostream&, const fractionType<T>&);
friend istream& operator>>(istream&, fractionType<T>&);
public:
//overload the assignment operator
const fractionType<T>& operator=(const fractionType<T>&);
//constructors
fractionType();
fractionType(const fractionType<T>&);
fractionType(const float&, const float&);
//desctructor
~fractionType();
//oveload the relational operators
bool operator==(const fractionType<T>&) const;
bool operator!=(const fractionType<T>&) const;
bool operator<=(const fractionType<T>&) const;
bool operator<(const fractionType<T>&) const;
bool operator>=(const fractionType<T>&) const;
bool operator>(const fractionType<T>&) const;
//overload the arithemetic operators
fractionType<T> operator+(const fractionType<T>&);
fractionType<T> operator-(const fractionType<T>&);
fractionType<T> operator*(const fractionType<T>&);
fractionType<T> operator/(const fractionType<T>&);
private:
T numenator; //variable to store the numerator
T denominator; //variable to store the denominator
};
template <class T>
fractionType<T>::fractionType(const float& nu, const float& de) {
numenator = nu;
if (de == 0) {
cout << "\n\tInvalid demoninator. " << "Default value considered for denominator. ";
denominator = 1;
}
else {
denominator = de;
}
}//end function fractionType
// Default constructor
template <class T>
fractionType<T>::fractionType() {
numenator = 0;
denominator = 1;
}
// copy constructor
template <class T>
fractionType<T>::fractionType(const fractionType<T>& rightFraction) {
numenator = rightFraction.numenator;
denominator = rightFraction.denominator;
}//end copy constructor
//Desctructor
template <class T>
fractionType<T>::~fractionType() {
}//end Desctructor
//oveload the relational operators
template <class T>
bool fractionType<T>::operator==(const fractionType<T>& rightFraction) const {
return ((numenator == rightFraction.numenator) && (denominator == rightFraction.denominator));
}//end function operator==
template <class T>
bool fractionType<T>::operator!=(const fractionType<T>& rightFraction) const {
return ((numenator != rightFraction.numenator) || (denominator != rightFraction.denominator));
}//end function operator!=
template <class T>
bool fractionType<T>::operator<(const fractionType<T>& rightFraction) const {
return ((numenator * rightFraction.denominator) < (denominator * rightFraction.numenator));
}//end function operator<
template <class T>
bool fractionType<T>::operator<=(const fractionType<T>& rightFraction) const {
return ((numenator * rightFraction.denominator) <= (denominator * rightFraction.numenator));
}//end function operator<=
template <class T>
bool fractionType<T>::operator>(const fractionType<T>& rightFraction) const {
return ((numenator * rightFraction.denominator) > (denominator * rightFraction.numenator));
}//end function operator>
template <class T>
bool fractionType<T>::operator>=(const fractionType<T>& rightFraction) const {
return ((numenator * rightFraction.denominator) >= (denominator * rightFraction.numenator));
}//end function operator>=
//overload the arithemetic operators
template <class T>
fractionType<T> fractionType<T>::operator+(const fractionType<T>& rightFraction) {
fractionType fractionHolder;
fractionHolder.numenator = (numenator * rightFraction.denominator) + (denominator * rightFraction.numenator);
fractionHolder.denominator = denominator * rightFraction.denominator;
return fractionHolder;
}//end function operator+
template <class T>
fractionType<T> fractionType<T>::operator-(const fractionType<T>& rightFraction) {
fractionType fractionHolder;
fractionHolder.numenator = (numenator * rightFraction.denominator) - (denominator * rightFraction.numenator);
fractionHolder.denominator = denominator * rightFraction.denominator;
return fractionHolder;
}//end function operator-
template <class T>
fractionType<T> fractionType<T>::operator*(const fractionType<T>& rightFraction) {
fractionType fractionHolder;
fractionHolder.numenator = numenator * rightFraction.numenator;
fractionHolder.denominator = denominator * rightFraction.denominator;
return fractionHolder;
}//end function operator*
template <class T>
fractionType<T> fractionType<T>::operator/(const fractionType<T>& rightFraction) {
fractionType fractionHolder;
//check for validity for division
if (rightFraction.numenator == 0 || rightFraction.denominator == 0) {
fractionHolder.numenator = 0;
fractionHolder.denominator = 1;
cout << "Invalid to perform division.";
}
else {
fractionHolder.numenator = numenator * rightFraction.denominator;
fractionHolder.denominator = denominator * rightFraction.numenator;
}//end else - if x
return fractionHolder;
}//end function operator+
//overload the stream extraction operators
template <class T>
ostream& operator<<(ostream& osObject, const fractionType<T>& myFraction) {
osObject << myFraction.numenator << "/" << myFraction.denominator;
return osObject;
}//end function operator<<
template <class T>
istream& operator>>(istream& isObject, fractionType<T>& myFraction) {
char ch;
isObject >> myFraction.numenator >> ch >> myFraction.denominator;
return isObject;
}//end function operator>>
#endif
As I stated I moved a lot of my code from a previous cpp file that used to run with all of this code and I put it into the header file that you can see above so that I could template my functions.
I have noticed if I put #include "main.cpp
in my header file that I get a ton more errors but the previous ones are gone. Now they are all errors for my main.cpp file like fractionType: undeclared identifier
type float unexpected
fraction1: undeclared indentifier
fraction2: undeclared indentifier
and it continues on in repeat for a total of 47 errors.