2016-12-14 113 views
0

我决定让我的HashTable类成为一个模板,这样我就可以练习制作模板,但遇到了问题。在我的HashTable<T>模板中,我有一个数据成员数组,称为Bucket s的items,它是HashTable<T>类中的一个结构。初始化items后,我无法访问模板代码中其他位置的Bucket的成员。无法访问模板内的结构成员

我曾尝试在结构和变量定义之前放置typenametemplate<class T>,但无法使其工作。

下面是一个代码片段,让我的错误'keyValue': undeclared identifier

#ifndef HASH_TABLE_ 
#define HASH_TABLE_ 

using namespace std; 
#include <iostream> 

template<class T> 
class HashTable 
{ 

public: 

HashTable(int numItems) { 
    if (numItems <= 0) { 
     throw std::invalid_argument("Invalid HashTable size"); 
    } 
    currItems = 0; 

    //B must be the next prime after 2 * numItems 
    B = 1000; 

    items = Bucket[B]; //allocate array of Buckets 

    items[0].keyVal; //ERROR: undeclared identifier 
} 

bool insert(T* newItem, int key) { 
    bool retVal = false; 

    if (currItems < B && newItem != NULL) { //cannot insert to full HashTable 
     int index = 0; 

     items[index].dataPtr = newItem; //ERROR:undeclared 
     items[index].keyVal = key;  //ERROR:undeclared 

     retVal = true; 
     currItems++; 
    } 

    return retVal; 
} 

private: 

struct Bucket { 
    T* dataPtr = NULL; 
    int keyVal = -1; 
}; 

Bucket * items; //array of buckets 
int B; //size of itemArray 
int currItems; //track number of items in HashTable 

}; 

#endif 

为什么items[x]无法访问桶,使得items[x].keyValitems[x].dataPtr不能用?我尝试了不同类型的初始化,例如items = new Bucket[B],但那也没有奏效,所以我假设我的错误在于模板方面。

我很欣赏任何指导!

+2

这段代码由于缺少nextPrime和getOpenBucket实现而不能编译,你也不能正确地分配项目(或者使用operator new [],或者甚至更好,将原始指针更改为智能项)。这里没有模板问题 –

+0

我删除了nextPrime和getOpenBucket。通过使用new [],你的意思是使用'items = new Bucket [B]'而不是我现在拥有的?因为这在过去给了我同样的错误。我不能使用智能指针,因为我必须在C++ '98 Linux机器上编译:( – shtuken

+0

是的,如果你想动态创建表,你需要分配内存。机器,你使用的并不重要 - if你有新的编译器可用,那么你可以使用新的标准 - 而且你仍然在这个代码中使用C++ 11特性(“int keyVal = -1;”)。在这些改变之后(并且把Bucket放在类的开头)我正在编译你的代码没有问题 –

回答

0

您必须在使用前声明Bucket

template<class T> 
class HashTable 
{ 
    struct Bucket { 
     T* dataPtr = NULL; 
     int keyVal = -1; 
    }; 


public: 

    HashTable(int numItems) { 
     if (numItems <= 0) { 
      throw std::invalid_argument("Invalid HashTable size"); 
     } 
     currItems = 0; 

     //B must be the next prime after 2 * numItems 
     B = nextPrime(numItems * 2); 

     items = new Bucket[B]; // <-- you forgot the 'new' 

     items[0].keyVal; //ERROR: undeclared identifier 
    } 

    bool insert(T* newItem, int key) { 
     bool retVal = false; 

     if (currItems < B && newItem != NULL) { //cannot insert to full HashTable 
      int index = getOpenBucket(key); 

      items[index].dataPtr = newItem; //ERROR:undeclared 
      items[index].keyVal = key;  //ERROR:undeclared 

      retVal = true; 
      currItems++; 
     } 

     return retVal; 
    } 

private: 


    Bucket * items; //array of buckets 
    int B; //size of itemArray 
    int currItems; //track number of items in HashTable 

}; 

ps。不要这样做:using namespace std;在头文件 - 永远。

这是邪恶的和反社会的,因为它毒害每个包含头文件的cpp文件的全局命名空间。这是确保没有人会使用你的图书馆的有保证的方式。

+0

即使移动结构声明到类的开始我仍然接收'hashtable.h(64):错误C2065:'keyValue':未声明的标识符错误。这可能与我在另一个类中声明我的HashTable有关?'HashTable * customers = new HashTable (10000);'感谢命名空间提示,我马上修复! – shtuken

+0

'items = new Bucket [B];'你忘了'new' –