-
May 27th, 2013, 04:25 PM
#1
Hashing problem with overloaded operator
I've got a hasing template function that is giving me the error '!=' : no operator found which takes a left-hand operand of type 'StateData' (or there is no acceptable conversion). I have a StateData class that I've overloaded the != operator once as a friend and another time as a member of the class. Still, I get the same error. I'm at a loss as to why this is happening. Please help!
StateData
Code:
class StateData
{
public:
StateData();
StateData(string, string, int, int);
void setStateInfo(string, string, int, int);
string getName();
string getCapitol();
int getYearAdmit();
int getOrder();
StateData getStateData();
friend bool operator<(StateData &, StateData &);
friend bool operator>(StateData &, StateData &);
// friend bool operator!=(StateData &, StateData &);
bool operator!=(StateData &);
friend bool operator==(StateData &, StateData &);
friend ostream &operator <<(ostream&, StateData);
friend istream &operator>>(istream &, StateData &);
private:
string name;
string capitol;
int yearAdmit;
int order;
};
StateData functions
Code:
StateData::StateData()
{
name = " ";
capitol = " ";
yearAdmit = 0;
order = 0;
}
StateData::StateData(string n, string c, int y, int o)
{
name = n;
capitol = c;
yearAdmit = y;
order = o;
}
void StateData::setStateInfo(string n, string c, int y, int o)
{
name = n;
capitol = c;
yearAdmit = y;
order = o;
}
string StateData::getName()
{ return name; }
string StateData::getCapitol()
{ return capitol; }
int StateData::getYearAdmit()
{ return yearAdmit; }
int StateData::getOrder()
{ return order; }
//StateData StateData::getStateData()
// { return this; }
bool operator<(StateData &right, StateData &left)
{ return (right.getName() < left.getName()); }
bool operator>(StateData &right, StateData &left)
{ return (right.getName() > left.getName()); }
bool operator==(StateData &right, StateData &left)
{ return (right.getName() == left.getName()); }
//bool operator!=(StateData &right, StateData &left)
//{ return (right.getName() != left.getName()); }
bool StateData::operator!=(StateData &left)
{ return (this->name != left.name); }
ostream &operator <<(ostream& out, StateData &a)
{
out << "State name: " << a.getName() << endl;
out << "State capitol: " << a.getCapitol() << endl;
out << "Year of admittance: " << a.getYearAdmit() << endl;
out << "Order of admittance: " << a.getOrder() << endl;
return out;
}
istream &operator>>(istream &in, StateData &a)
{
string n, c;
int y, o;
cout << "Enter State name: ";
getline(cin, n);
cout << "Enter State capitol: ";
getline(cin, c);
cout << "Enter year of admittance: ";
cin >> y;
cout << "Enter order of admittance: ";
cin >> o;
a.setStateInfo(n, c, y, o);
return in;
}
hashT class
Code:
template<class elemType>
class hashT
{
private:
elemType *HTable; //pointer to the hash table
int *indexStatusList; //pointer to the array indicating
//the status of a position in the
//hash table
int length; //number of items in the hash table
int HTSize; //maximum size of the hash table
};
insert function - where error occurs
Code:
template <class elemType>
void hashT<elemType>::insert(int hashIndex, const elemType& rec)
{
int pCount;
int inc;
pCount = 0;
inc = 1;
while(indexStatusList[hashIndex] == 1
&& HTable[hashIndex] != rec
&& pCount < HTSize / 2)
{
cout <<"inc = " << inc << endl;
pCount++;
hashIndex = (hashIndex + inc ) % HTSize;
cout << "new hashIndex = " << hashIndex << endl;
inc = inc + 2;
}
if(indexStatusList[hashIndex] != 1)
{
HTable[hashIndex] = rec;
cout << "HTable["<< hashIndex <<"]" <<" = " << rec << endl;
indexStatusList[hashIndex] = 1;
length++;
}
else
if(HTable[hashIndex] == rec)
cerr<<"Error: No duplicates are allowed"<<endl;
else
cerr<<"Error: The table is full. "
<<"Unable to resolve the collision"<<endl;
}
here is the main
Code:
#include <iostream>
#include <fstream>
#include <string>
#include "hashT.h"
#include "stateData.h"
using namespace std;
int hashFunc(string name, int size);
int main()
{
hashT<StateData> HashTable(50);
int size = 15;
ifstream infile;
infile.open("states.txt");
if(!infile)
{
cout << "Error reading states file.\n";
exit(1);
}
char ch;
int year, order, key;
string state, capitol;
bool found;
getline(infile, state);
while(infile)
{
getline(infile, capitol);
infile >> year;
infile >> order;
StateData temp;
temp.setStateInfo(state, capitol, year, order);
infile.get(ch);
key = hashFunc(state, size);
HashTable.insert(key, temp);
getline(infile, state);
}
HashTable.print();
//cout<<"Enter item to be deleted: ";
//cin>>num;
//cout<<endl;
infile.close();
system("pause");
return 0;
}
int hashFunc(string name, int size)
{
int i, sum, len;
i= 0;
sum = 0;
len = name.length();
for (int k=0; k < 15 - len; k++)
name = name + ' ';
for (int k = 0; k < 5; k++)
{
sum = sum + static_cast<int>(name[i]) * 128 * 128
+ static_cast<int>(name[i+1]) * 128
+ static_cast<int>(name[i+2]);
i = i+3;
}
return sum % size;
}
-
May 27th, 2013, 04:44 PM
#2
Re: Hashing problem with overloaded operator
Here,
void hashT<elemType>::insert(int hashIndex, const elemType& rec)
elemType (which is a StateData) is passed by const reference, whereas here
// friend bool operator!=(StateData &, StateData &);
bool operator!=(StateData &);
it's passed by reference only (without the const). So in effect you have no fitting operator!= signature.
It's easy to test whether this is the problem. You just remove const here like,
void hashT<elemType>::insert(int hashIndex, elemType& rec)
and it should work.
-
May 27th, 2013, 04:51 PM
#3
Re: Hashing problem with overloaded operator
That fixed it! Thank you so much! One more question, maybe I could use the friend function and change the StateData objects to const reference?
-
May 27th, 2013, 11:34 PM
#4
Re: Hashing problem with overloaded operator
Originally Posted by luvCats
That fixed it! Thank you so much! One more question, maybe I could use the friend function and change the StateData objects to const reference?
Yes, you can do that. I would use a friend function with parameters by const reference. Const reference is the preferred passing mode if you don't intend to change the parameters.
What I suggested was only because it was the easiest way to quickly test whether this was the problem.
-
May 28th, 2013, 11:00 AM
#5
Re: Hashing problem with overloaded operator
Also, when designing your own containers, you ideally want to attempt to design your conatiner class in such a way that you only need ONE comparator/ordering operator.
If you look at the STL implementations, all the "weak ordering" containers and functions only use an < operator. Handy for those using the class since they only need to provide a single operator function as well.
Here you have a <, >, !=, ==
They might be needed for other things, but from a pure pov of the container, you want to avoid this.
Additionally, it may also be interesting to templatize the comparator/ordering operator so you can overload it at template instantiation rather than only having the option to overload an operator in your element class. This could be important if you want to store classes that don't come with an operator and which you can't change, and where deriving may be awkward or even unfeasible. Have a look at std::map to see how they templatize the comparator to default to less<Key>...
Last edited by OReubens; May 28th, 2013 at 11:06 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|