Reputation: 31
I have read several threads on here and think I have set this up accordingly. I believe the issue is that I am using a * and I don't have the overloaded << setup properly somehow, ie - the parameter definition is incorrect. The problem is is compiles and runs successfully, so I haven't a clue as to where I am making the mistake.
I am really sorry if this has been answered before, but I cannot find it.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <list>
#include <exception>
using namespace std; //Allows us to not prepend std:: to many things.
template<class t>
class HashingTable
{
public:
HashingTable();
HashingTable(int size);
void insert(const char *x);
private:
int x = 0;
vector<list<const char *>> hashedLists;
int currentSize;
int hash(const char * key);
friend std::ostream& operator << (std::ostream & os, const HashingTable<t>);
};
template<class t> std::ostream& operator<< (ostream & os, const HashingTable<t> &ht)
{
const int listSize = ht.size();
for (unsigned int i = 0; i < listSize; i++)
{
list<const char *> searchList = ht[i];
for (std::list<const char *>::const_iterator si = std::next(searchList.begin(), listSizeLimit); si != searchList.end(); ++si) //for each value in hashed list.
cout << *si << " ";
}
return os;
};
template<class t>
int HashingTable<t>::hash(const char * key) {
return key[0] - 'A';
};
template<class t>
HashingTable<t>::HashingTable(int size)
{
hashedLists.resize(size);
};
template<class t>
HashingTable<t>::HashingTable()
{
hashedLists.resize(0);
};
template<class t>
void HashingTable<t>::insert(const char *x) {
//string tempStr(x);
unsigned int hashVal = hash(x);
if (hashedLists.size() < (hashVal + 1)) //if the number of lists in the current vector is less than the resize value then...
hashedLists.resize(hashVal + 1); //resize the hashedLists vector
list<const char *> iList = hashedLists[hashVal];
if (std::find(iList.begin(), iList.end(), x) == iList.end())
{
iList.push_back(x);
hashedLists[hashVal] = iList;
}
currentSize++;
};
int main() /* A sample main program */
{
HashingTable<char*>* mht;
char* Names[25] = { "AB", "AC", "AE", "AZ",
"BA","BM", "BJ", "BZ",
"CA", "CX", "CZ", "CZZ",
"EJ", "EP", "EF", "ES",
"QW", "QE", "QR", "QD",
"SA", "SD", "SF", "SS", "SJ" };
int i;
mht = new HashingTable<char*>(0);
for (i = 0; i < 25; i++)
(*mht).insert(Names[i]);
cout << "Printing the hash table after inserting...." << endl;
cout << *mht;
cout << endl;
return 0;
}
Thanks for any insight.
Upvotes: 0
Views: 92
Reputation: 283634
Your friend declaration is quite useless and actually harmful. It doesn't match the actual function body, so it won't help it be found or give extra access to private members, and it will compete with the defined operator during overload resolution.
When the friend does get selected, the compiler emits a call to a function that never possesses a body, causing your unresolved external error.
This type of friend declaration declares a family of non-template functions in the enclosing namespace. There is no syntax for defining them out-of-line.
Remove the friend declaration. Or move the body inline, in which case you should also fix the second parameter to be a const reference, not a copy.
When you do start invoking the operator function body you've written, you're going to get additional errors such as ht.size()
not existing. Do not assume these errors mean your usage of the operator is wrong -- they actually mean your usage is right, and the compiler now is attempting to resolve dependent names in the operator function body.
Upvotes: 0
Reputation: 303007
In:
cout << (mht);
The unnecessarily parenthesized mht
is of type HashingTable<char*> *
. You provided an overload of operator<<
that takes a HashingTable<T> const&
. Those aren't the same, so your overload isn't considered.
What you meant was:
cout << *mht;
Upvotes: 3