***Solution provided by JVApen for this particular case. I had to inline the operator overloads in the item.h file because I wasn't using an implementation file.
I've created a project that has 2 header files. One for an item structure and the other for a list that uses the structure. I'm getting the following errors and I know if I wrap the structure header in the nameless namespace they'll go away, but what's the underlying cause and how can I avoid it in the future?
1>Project2.obj : error LNK2005: "class std::basic_istream > & __cdecl operator>>(class std::basic_istream > &,struct item &)" (??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@AAUitem@@@Z) already defined in linkedList.obj 1>Project2.obj : error LNK2005: "class std::basic_ostream > & __cdecl operator<<(class std::basic_ostream > &,struct item const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABUitem@@@Z) already defined in linkedList.obj
I did not create an implementation file for the struct, everything is prototyped and defined in the header file, is that what is causing it?
I've included the item.h into my linkedList.h as show below:
item.h
#pragma once
#include <iostream>
#include <iomanip>
#include <string>
struct item {
std::string name;
double price;
int currentInv;
int minInv;
item(std::string name = "default", double price = 0,
int currentInv = 0, int minInv = 0)
: name(name), price(price), currentInv(currentInv), minInv(minInv)
{}
bool operator<(const item& rhs) {
return (this->name < rhs.name);
}
bool operator>(const item& rhs) {
return (this->name > rhs.name);
}
bool operator==(const item& rhs) {
return (this->name == rhs.name);
}
bool operator<=(const item& rhs) {
return ((this->name < rhs.name) || (this->name == rhs.name));
}
bool operator>=(const item& rhs) {
return ((this->name > rhs.name) || (this->name == rhs.name));
}
};
std::ostream& operator<<(std::ostream& out, const item& printMe) {
out << std::fixed << std::setprecision(2);
return (out << std::setw(31) << std::left << printMe.name << ' ' <<
std::right << std::setw(6) << printMe.price << ' ' << std::setw(3) <<
printMe.currentInv << ' ' << std::setw(3) << printMe.minInv);
}
std::istream& operator>>(std::istream& in, item& fillMe) {
return (in >> fillMe.name >> fillMe.price >> fillMe.currentInv >>
fillMe.minInv);
}
linkedList.h
#pragma once
#include "item.h"
class List {
private:
//--- Node Class
class node {
public:
//--- Node Variables
item data{}; // item struct
node* next; // ptr to next node
//--- Node Constructors
node()
: next(NULL) {}
node(item& data, node* ptr = NULL)
: data(data), next(ptr) {};
};
//--- Class Variables
int mySize; // list Size
node* first; // first node
public:
//--- List Constructors
List();
List(List& original); // copy constructor
//--- List Destructor
~List(); // destructor
//--- List Overrides
List& operator=(const List rhs); // = overload
//--- List Public Functions
bool empty();
int nodeCount();
int search(const std::string findMe); // find a piece of data
void addItem(item& addme); // add node
void changeItem(); // change an item
void display(std::ostream& out); // print out
void displayReversed(std::ostream& out); // reverse print
void remove(int index); // remove node at index
void fileOut(std::ostream out); // end of program file
private:
//---List Private Functions
void addItemPrivate(item& addme, node* ptr);
};
std::ostream& operator<<(std::ostream& out, const List& outMe);