2013-04-02 79 views
0

我不得不创建一个模板化的哈希表,但是无论何时我试图编译它,我都会收到几个错误,说明有未声明的标识符,并且模板在它们之后不是类型名称。问题特别在hashTable类中。哈希表模板实现的问题

//Author: Angelo Todaro 
//hashTable.h 
//File for the implementation of the hash table 

#include "person.h" 
#include "student.h" 
#include "administrator.h" 
#include "faculty.h" 
#include <list> 

using namespace std; 
#ifndef hashTable_H 
#define hashTable_H 


template<class T, typename T2, typename T3> 
class hashTable{ 
public: 
    /*Default Constructor 
    *Constructs an object of the hashTable class*/ 
    hashTable(); 

    /*Default Destructor 
    *Destructs an object of the hashTable class*/ 
    ~hashTable(); 


    /*Accessor Method for size of table 
    *Provides user access to the value of the size of the table*/ 
    T getSize() const; 

    /*Modifier Method for size of table 
    *Provides the user access to change the value of the size of the table*/ 
    void setSize(T newSize); 

    /*getEntry 
    *Retrieves an entry from the table based on the key*/ 
    T2 getEntry(T3 searchEntry); 

    /*putEntry 
    *Puts a new entry in its proper location in the table*/ 
    void putEntry(T2 newEntry); 

    /*removeEntry 
    *Removes an entry from its location in the table*/ 
    void removeEntry(T3 searchEntry); 

private: 
    T size; 
    list<T2> table[size]; 
    list<T2>::iterator iter; 

    /*hashKey 
    *Hashes the given key in order to find its location in the table*/ 
    T hashKey(T3 key); 

}; 

#endif 

//Implementation section 


    /*Default Constructor 
    *Constructs an object of the hashTable class*/ 
    template<typename T, typename T2, typename T3> 
    hashTable<T,T2,T3>::hashTable(){ 

    } 

    /*Default Destructor 
    *Destructs an object of the hashTable class*/ 
    template<typename T, typename T2, typename T3> 
    hashTable<T,T2,T3>::~hashTable(){ 

    } 


    /*Accessor Method for size of table 
    *Provides user access to the value of the size of the table*/ 
    template<typename T, class T2, class T3> 
    T hashTable<T,T2,T3>::getSize() const{ 
     return size; 
    } 

    /*Modifier Method for size of table 
    *Provides the user access to change the value of the size of the table*/ 
    template<typename T, typename T2, typename T3> 
    void hashTable<T,T2,T3>::setSize(T newSize){ 
     size = newSize; 
    } 

    /*getEntry 
    *Retrieves an entry from the table based on the key*/ 
    template<typename T, typename T2, typename T3> 
    T2 hashTable<T,T2,T3>::getEntry(T3 searchEntry){ 
     int key = hashKey(searchEntry); 
     if(table[key]==NULL) 
     { 
      return -1; 
     } 
     else 
     { 
      while(iter != table[key].end() || searchEntry != *iter->getKey()) 
       iter++; 
      if(iter == table[key].end() && searchEntry != *iter->getKey()) 
      { 
       return -1; 
      } 
      else 
      { 
       *iter->print(); 
      } 
     } 
    } 

    /*putEntry 
    *Puts a new entry in its proper location in the table*/ 
    template<typename T, typename T2, typename T3> 
    void hashTable<T,T2,T3>::putEntry(T2 newEntry){ 
     int key = hashKey(newEntry->getKey()); 
     table[key].push_back(newEntry); 
    } 

    /*removeEntry 
    *Removes an entry from its location in the table*/ 
    template<typename T, typename T2, typename T3> 
    void hashTable<T,T2,T3>::removeEntry(T3 searchEntry){ 
     int key = hashKey(searchEntry); 
     while(iter != table[key].end() || searchEntry != *iter->getKey()) 
      iter++; 
     if(*iter->getKey() == searchEntry) 
      table[key].erase(iter); 
     else 
      cout << "Can not delete Person (M" << number << "), NOT found!" << endl; 
    } 

    /*hashKey 
    *Hashes the given key in order to find its location in the table*/ 
    template<typename T, typename T2, typename T3> 
    T hashTable<T,T2,T3>::hashKey(T3 key){ 
      return key/1000; 
    } 

这里是我收到

1>------ Build started: Project: lab12, Configuration: Debug Win32 ------ 
1>Build started 4/2/2013 3:20:56 PM. 
1>InitializeBuildStatus: 
1> Touching "Debug\lab12.unsuccessfulbuild". 
1>ClCompile: 
1> recordsOffice.cpp 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(50): error C2327: 'hashTable<T,T2,T3>::size' : is not a type name, static, or enumerator 
1>   c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(57) : see reference to class template instantiation 'hashTable<T,T2,T3>' being compiled 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(50): error C2065: 'size' : undeclared identifier 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(51): warning C4346: 'std::list<T2>::iterator' : dependent name is not a type 
1>   prefix with 'typename' to indicate a type 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(51): error C2146: syntax error : missing ';' before identifier 'iter' 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(51): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(50): error C2327: 'hashTable<T,T2,T3>::size' : is not a type name, static, or enumerator 
1>   with 
1>   [ 
1>    T=int, 
1>    T2=Person, 
1>    T3=int 
1>   ] 
1>   c:\users\angelo\google drive\advanced data structures\lab12\lab12\recordsoffice.h(35) : see reference to class template instantiation 'hashTable<T,T2,T3>' being compiled 
1>   with 
1>   [ 
1>    T=int, 
1>    T2=Person, 
1>    T3=int 
1>   ] 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(50): error C2065: 'size' : undeclared identifier 
1> lab12-main.cpp 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(50): error C2327: 'hashTable<T,T2,T3>::size' : is not a type name, static, or enumerator 
1>   c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(57) : see reference to class template instantiation 'hashTable<T,T2,T3>' being compiled 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(50): error C2065: 'size' : undeclared identifier 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(51): warning C4346: 'std::list<T2>::iterator' : dependent name is not a type 
1>   prefix with 'typename' to indicate a type 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(51): error C2146: syntax error : missing ';' before identifier 'iter' 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(51): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(50): error C2327: 'hashTable<T,T2,T3>::size' : is not a type name, static, or enumerator 
1>   with 
1>   [ 
1>    T=int, 
1>    T2=Person, 
1>    T3=int 
1>   ] 
1>   c:\users\angelo\google drive\advanced data structures\lab12\lab12\recordsoffice.h(35) : see reference to class template instantiation 'hashTable<T,T2,T3>' being compiled 
1>   with 
1>   [ 
1>    T=int, 
1>    T2=Person, 
1>    T3=int 
1>   ] 
1>c:\users\angelo\google drive\advanced data structures\lab12\lab12\hashtable.h(50): error C2065: 'size' : undeclared identifier 
1> Generating Code... 
1> 
1>Build FAILED. 
1> 
1>Time Elapsed 00:00:01.84 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 
+0

你如何使用这个散列表?我问,因为目前有三种不同的模板类型在播放('T'大小,'T2'你存储的,'T3'你散列找到存储的'T2')。其中一些似乎没有必要。 'T'(size)应该是'size_t'(因此_not_模板)。为什么将大小作为模板参数?如果我使用散列表并提供'T' ='std :: string',会怎样? 'T3'不是绝对必要的,(你应该能够使用'T2'来找到一个'T2',但是如果'T2'不是微不足道的构造就可以理解。 – Chad

+0

如果你把'T'模板化为尺寸,因为你希望散列表的大小可以在编译时配置,你不应该在那里使用typename,而应该使用size_t。像这样:http://ideone.com/2RCc1M – Chad

+0

T3是模板化的唯一原因是因为T2是一个类包含几个不同的整数和字符串,T3只是让我更容易使用字符串而不是int来建立索引 – todaroa

回答

1

问题的错误在这里

private: 
    T size; 
    list<T2> table[size]; 
    list<T2>::iterator iter; 

1这是不对的。

list<T2> table[size]; 

这不是如何声明列表。即使这是一个正常的阵列,你也不能在那里使用size,因为大小不是static。创建hashTable实例来分配数组时,编译器不知道size的值。

应该只是

list<T2> table; 

2这就需要类型名称

list<T2>::iterator iter; 

编译器需要知道您声明iter和期望一个类型说明符。您可以通过在声明中添加typename来帮助他。

应该

typename list<T2>::iterator iter; 

所以要summerize

T size; 
list<T2> table; // HERE 
typename list<T2>::iterator iter; // HERE 

如果你想要一个数组列表的(而不是一个列表)。你可以使用矢量(而不是数组)的列表。

vector< list<T2> > table; OR 
list< list<T2> > table; 

(根据您的需要。More info on containers

但要注意这一点。复制这些对象可能很昂贵。如果可以,请通过引用或使用指针。

+0

因此,为了创建列表数组,我应该在构造函数中做这些事情? – todaroa

+0

我编辑了答案。 – 2013-04-02 21:08:58

+0

好吧,这使得它更清晰。我们刚刚了解到STL,我甚至没有想过要使用矢量而不是数组。 – todaroa