2013-10-14 19 views
0

我爲了更多地瞭解聯想的地圖一般實現在C++中一個HashMap,一切都很好地工作,除了一個棘手的問題 - 我想程序員可以創建任意參數化的地圖(如[使用std::string例如] HashMap<string,string*>HashMap<string,string>,並且HashMap<string*,string>等都是合法的)。如何處理C++ HashMap get(key)函數中的未命中?

麻煩的是,在HashMap::get(int key_data)功能未命中(其中給定密鑰不匹配任何映射值)返回的映射值不能簡單地將NULL,如果我支持具有對象作爲映射值。我能有get(...)函數總是返回一個指針的參數化映射值的類型,但如果該類型已經是一個指針,我不能使用一元&運營商,如果它是一個對象,我必須使用&操作。我絕對不想使用RTTI,所以問題如下:

如何從我的HashMap::get()函數中允許對象和指針到對象的返回類型,這也是需要允許未命中的?

請記住我使用GCC 4.7與C++ 11接通,因此所有C++ 11的功能和注意事項適用。下面遵循我的HashMap::get()功能到目前爲止使用「總是返回一個指向任何value_data恰好是」範式:

template <class key_data,class value_data> value_data* 
HashMap<key_data,value_data>::get(key_data dk) { 

    int key = keyGen(dk); 

    int hash_val = HashFunc(key); 
    HashNode* entry = _table[hash_val]; 

    while (entry != 0) { 
     if (entry->getCurrentKey() == key) { 

      //value_data val = entry->getCurrentValue(); //this temporary will be 
      //gone from the stack quickly and therefore the returned pointer to a 
      //pointer (if value_data is a pointer) will segfault 

      return &(entry->getCurrentValue()); //this should be legal and yield 
      //a pointer to a pointer (iff value_data was a pointer), but instead 
      //I get a compiler error claiming 
      //operator & requires an lvalue operand... 
     } 

     entry = entry->next(); 

    } 

    printf("Your get of int key %i resulted in no hits." 
      "The returned pointer to Value is NULL!\n",key); 


    return NULL; 
} 

正如註釋狀態,線路return &(entry->getCurrentValue());拋出一個編譯器錯誤,指出運營商&需要一個左值操作數。我可以通過將value_data臨時壓入堆棧擺脫錯誤的,但是,這將導致一個段錯誤,當我真正嘗試使用它,因爲返回的指針將是無效的幾乎瞬間。只需用引用抽象掉的語法問題不會是因爲在這種情況下,未命中工作無法通過收益NULL實現(ISO要求引用,不像原始指針,指向有效左值)。

如果任何人有關於處理返回的引用可能是'無效'的建議(就像一個虛擬對象,可以查詢其他所有東西繼承的虛擬對象),我也對這些引用開放。解決這個

+6

你爲什麼不看看標準庫如何解決呢? –

+1

「我得到一個編譯錯誤,聲稱運營商需要一個左操作數...」我的價值(或指針)打賭'getCurrentValue'回報?如果是這樣,它返回一個prvalue。爲了使其編譯,使其返回一個參考。 (這不會解決根本問題,雖然。) – dyp

+0

getCurrentValue()無論value_data被參數化的回報;可能是一個對象或一個指針在你的榜樣(我不支持引用,因爲他們不輕易讓如上面的「失誤」) – CCJ

回答

1

一種可能的方式是局部模板特殊化。有關指針的示例,請參見this other question

基本上(從答案那裏複製的),你需要

template <class I> 
class GList<I*> 
{ 
    ... 
}; 

爲任何指針類型提供列表的專用版本。

+0

hmm,所以像'template class HashMap {...處理映射的對象在這裏};'和'template class HashMap​​{...這裏處理映射的指針};'?編譯器如何處理HashMap參數化的情況,用value_data槽中的指針開始(HashMap ) - 是否足夠聰明,可以將value_data的數據類型標識爲std :: string,然後檢查是否還應用指針或引用運算符來生成正確的代碼來處理對象與指針? – CCJ

+0

我會試驗一下,稍後回覆;感謝您的建議! – CCJ

+0

正確,有一點按摩和幫助從上面的評論工作。謝謝! – CCJ

相關問題