2009-10-24 24 views
3

我正在爲我的數據結構類編寫一個哈希表,並且我想爲我的實現添加一點語法糖。重載括號訪問和分配C++

template <typename HashedObj, typename Object> 
Object & Dictionary<HashedObj, Object>::operator[](HashedObj & key) 
{ 
    return items.lookup(key); 
} 

,當我做類似的cout < <的dict [ 「的myKey」]這工作正常。 但是我怎樣才能使用括號進行賦值?喜歡的東西:

dict["mykey"] = "something"; 

不,這不是我的家庭作業(沒有雙關語意),我只是想學C++好一點的一部分。

+0

順便說一句,你用什麼類型的'HashedObj'當你聲明你的Dictionary用於字符串鍵?像上面例子中的「mykey」一樣。 – AnT 2009-10-24 18:38:19

+0

因爲你正在返回一個引用,賦值操作符應該按照你期望的方式工作。唯一的問題發生在lookup()找不到key時,你會怎麼做? – 2009-10-24 20:01:01

+0

在我的測試中,我使用字符串: Dictionary dict; – Matt 2009-10-24 20:28:49

回答

5

目前尚不清楚你到底在問什麼。您提交的代碼已經支持分配。只要做到這一點,並隨時工作(或至少應該編譯)。它使您的超載[]被使用的賦值運算符的哪一面完全沒有區別。它在左側(LHS)的工作方式與在作業的右側(RHS)的工作方式完全相同(或作爲<<的操作數,如在原始文章中那樣)。您的[]返回對Object的引用,然後實際分配由您的Object類型的賦值運算符處理,這意味着[]本身並未真正涉及實際分配。

這裏真正的問題是你希望你的[]在某些特殊情況下行事。如果你的鑰匙不在桌子上,會發生什麼?參考什麼Object是你的lookup要在這種情況下返回?

從您發佈的內容中弄清楚這一點是不容置疑的。我看到它返回一個參考,所以返回NULL是沒有問題的。它是否爲給定的鍵插入一個新的空的Object?如果是這樣,那麼你不必做任何事情。您的[]已經完全準備好用於分配的LHS。 (這是如何std::map作品,BTW []

如果您lookup返回到一個特殊的「保鏢」 Object參考,你必須採取特殊步驟。您可能不想將任何內容分配給「警衛」對象,因此您必須以某種方式「禁用」其賦值運算符,然後完成。其餘的應該按原樣工作。

如果您的lookup在不存在密鑰的情況下引發異常,那麼您必須決定在分配的LHS上使用[]時是否這樣。如果是這樣,那麼你不需要做任何事情。如果沒有,那麼它將需要一些額外的工作...

因此,再次,如果你通過一個不存在的密鑰lookup會發生什麼?

P.S.此外,通常將[](和lookup)與const HashedObj&參數或僅HashedObj參數一起聲明會更有意義。在你的例子中,非const引用看起來很奇怪,可能會導致一些(實際上,在大多數情況下)的問題。我很驚訝它現在適合你...

+0

我想它已經支持分配。我覺得這會比這更難!我並不太擔心這個簡單程序的特殊情況,但感謝您指出它們。 – Matt 2009-10-24 17:48:00

+0

我支持通過=運算符進行賦值。 – Alexandru 2009-10-24 18:18:50

+0

@Matt:爲了100%清楚,'operator []'返回一個'Object'引用。它是必須支持分配的「對象」類。 'Dictionary'類也可以支持賦值,但在這裏不會執行。 – 2009-10-24 18:23:36

3

您需要重載2次。一個是const,它將是data access部分,另一個將返回一個引用,它將作爲「setter」。

2

您要找的是和std::map中的重載支架操作符相似的功能。在std::map中,括號操作符執行查找並返回對與特定鍵相關聯的對象的引用。如果該映射不包含任何與該鍵關聯的對象,則該操作員使用默認構造函數將新對象插入到映射中。

所以,如果你有std::map<K,V> mymap,然後調用mymap[someKey]要麼返回引用與someKey相關聯的值,否則將通過調用V()(V的默認構造函數),然後返回創建V類型的新對象對新對象的引用,它允許調用者爲對象分配一個值。