2016-12-14 30 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' –