Reputation: 414
I'm trying to write a code for a template HashTable but I'm blocked with some compilation errors.
Class HashTable:
template<typename Key, typename Value>
class HashTable{
class HashElement{
friend class HashTable;
Key k_;
Value v_;
public:
HashElement();
HashElement(const Key&, const Value&);
~HashElement();
};
unsigned int bucket_num_;
unsigned int size_;
std::vector<lista<HashElement*>*>* table_;
HashFunction h_;
unsigned int hash(const Key&)const;
int rehash();
public:
HashTable();
HashTable(const unsigned int);
HashTable(const HashTable &);
~HashTable();
unsigned int HashTableGetSize(){return size_;};
unsigned int HashTableGetBucketNumber(){return bucket_num_;};
int HashTableInsert(const Key&, const Value&);
bool IsInHashTable(const Key&, const Value&) const;
bool IsEmptyBucket(const unsigned int) const;
};
The data type lista I'm using is linked list already tested.
To use several hash function depending on the key's type y develop the following class:
class HashFunction{
public://son todos metodos de sobrecarga
unsigned int on(const int&) const;
unsigned int on(const std::string&) const;
unsigned int on(const float&) const;
};
Every function on hashes for a different data type.
The errors I'm getting from gcc compiler are:
HashTable.hpp: In constructor ‘HashTable<Key, Value>::HashTable()’:
HashTable.hpp:118:12: error: expected nested-name-specifier
HashTable.hpp:118:12: error: expected ‘(’
HashTable.hpp:118:12: error: expected ‘;’
HashTable.hpp:119:16: error: ‘temp’ was not declared in this scope
HashTable.hpp: In constructor ‘HashTable<Key, Value>::HashTable(unsigned int)’:
HashTable.hpp:130:12: error: expected nested-name-specifier
HashTable.hpp:130:12: error: expected ‘(’
HashTable.hpp:130:12: error: expected ‘;’
HashTable.hpp:131:16: error: ‘temp’ was not declared in this scope
HashTable.hpp: In member function ‘int HashTable<Key, Value>::rehash()’:
HashTable.hpp:164:11: error: expected nested-name-specifier
HashTable.hpp:164:11: error: expected ‘(’
HashTable.hpp:164:11: error: expected ‘;’
HashTable.hpp:171:8: error: ‘aux’ was not declared in this scope
HashTable.hpp:175:11: error: ‘aux’ was not declared in this scope
HashTable.hpp: In instantiation of ‘HashTable<Key, Value>::HashTable() [with Key = std::basic_string<char>; Value = int]’:
Hashtest.cpp:10:29: required from here
HashTable.hpp:119:3: error: no match for ‘operator*’ in ‘**(((HashTable<std::basic_string<char>, int>*)this)->HashTable<std::basic_string<char>, int>::table_ + ((sizetype)(i * 12u)))’
HashTable.hpp: In instantiation of ‘HashTable<Key, Value>::~HashTable() [with Key = std::basic_string<char>; Value = int]’:
Hashtest.cpp:10:29: required from here
HashTable.hpp:149:3: error: no match for ‘operator*’ in ‘**(((HashTable<std::basic_string<char>, int>*)this)->HashTable<std::basic_string<char>, int>::table_ + ((sizetype)(i * 12u)))’
It seems to be having a problem every time I ask for dynamic memory:
new lista<HashElement*>()
I don't really know how to solve the problem.
These are the methods:
template<typename Key, typename Value>
HashTable<Key,Value>::HashElement::HashElement()
{
}
template<typename Key, typename Value>
HashTable<Key,Value>::HashElement::HashElement(const Key &k, const Value &v) : k_(k),v_(v)
{
}
template<typename Key, typename Value>
HashTable<Key,Value>::HashElement::~HashElement()
{
}
template<typename Key, typename Value>
HashTable<Key,Value>::HashTable() : bucket_num_(BUCKET_INIT_NUM), size_(0)
{
this->h_=HashFunction();
table_ = new std::vector<lista<HashElement*>*>(BUCKET_INIT_NUM);
for(unsigned int i=0; i < bucket_num_; i++)
{
typename lista<HashElement*>* temp = new lista<HashElement*>();
*table_[i] = temp;
}
}
template<typename Key, typename Value>
HashTable<Key,Value>::HashTable(const unsigned int b) : bucket_num_(b), size_(0)
{
this->h_=HashFunction();
table_ = new std::vector<lista<HashElement*>*>(BUCKET_INIT_NUM);
for(unsigned int i=0; i < bucket_num_; i++)
{
typename lista<HashElement*>* temp = new lista<HashElement*>();
*table_[i] = temp;
}
}
template<typename Key, typename Value >
HashTable<Key,Value>::HashTable(const HashTable &orig)
{
table_ = new std::vector<lista<HashElement*>*>(orig);
h_=HashFunction();
h_=orig.h_;
size_=orig.size_;
bucket_num_=orig.bucket_num_;
}
template<typename Key, typename Value>
HashTable<Key,Value>::~HashTable()
{
for(unsigned int i=0; i < bucket_num_ ; i++)
delete *table_[i];
delete table_;
bucket_num_=0;
size_=0;
}
template<typename Key, typename Value>
unsigned int HashTable<Key,Value>::hash(const Key &k) const
{
return this->h_.on(k);
}
template<typename Key, typename Value>
int HashTable<Key,Value>::rehash()
{
typename HashTable<Key,Value> * aux(bucket_num_*INCREASE_FACTOR);
bucket_num_ = bucket_num_*INCREASE_FACTOR;
for(unsigned int i=0; i<bucket_num_; i++)
{
typename lista<HashElement*>::iterador it;
for(it=table_[i]->primero(); !it.extremo(); it.avanzar())
{
if( aux->HashTableInsert(it.dato()->k_ ,it.dato()->v_) == -1 )
return -1;
}
}
table_ = aux->table_;
}
template<typename Key, typename Value>
int HashTable<Key,Value>::HashTableInsert(const Key &k, const Value &v)
{
if(IsInHashTable(k,v)==true)
return -1;
unsigned int bucket = hash(k) % bucket_num_;
HashElement *e(k,v);
table_[bucket]->insertar(e);
return 0;
}
template<typename Key, typename Value>
bool HashTable<Key,Value>::IsEmptyBucket(const unsigned int pos) const
{
if(pos>bucket_num_) return false;
return (table_[pos]->vacia()==true)?true:false;
}
template<typename Key, typename Value>
bool HashTable<Key,Value>::IsInHashTable(const Key & k, const Value & v) const
{
unsigned int bucket=hash(k)%bucket_num_;
typename lista<HashElement*>::iterador it;
for(it=table_[bucket]->primero(); !it.extremo(); it.avanzar())
{
if(it.dato()->v_ == v) return true;
}
return false;
}
Upvotes: 0
Views: 2372
Reputation: 18972
You don't need (and mustn't have) the typename
in typename lista<HashElement*>* temp = ...
or in typename HashTable<Key,Value> * aux(bucket_num_*INCREASE_FACTOR);
.
Its purpose is to clarify whether a nested name of a template specialization is a type or not; you don't have a nested name (i.e. one with a ::
in it) there.
But you do need it in typename lista<HashElement*>::iterador it;
- here it's needed to tell the compiler that the iterador
you are referring to is a type.
Upvotes: 1