這個問題是密切相關的另一個問題:你 你想要的行爲,當您訪問不是在 分配等一個不存在的價值?換句話說,你想要什麼,當你寫的情況發生:
std::cout << hashTable[string] << std::endl;
和string
是不存在的表?
有兩種可能的方法:您可以認爲它是一個錯誤,並且 會拋出異常或中止,或類似的;或者您可以返回 某種默認值,使用默認的構造函數構建,或者由客戶端提供的 。
標準映射和unordered_map採用第二種方法,使用默認構造函數 構造一個新值。這允許一個非常簡單的 解決方案:如果operator[]
不存在,您插入它,用默認值初始化它 。然後您返回對它的引用; hashTable[string] = newString;
通過對 的引用分配已經存在的值。
在許多使用情況,第一種方法將是最好(或許還有一個 contains
功能,因此您可以測試前面的operator[]
是否會發現一些與否)。爲了實現第一種方法,你必須 首先實現每種類型的訪問的具體功能:
template <typename Key, typename Value>
class HashTable
{
public:
Value* get(Key const& key) const;
void set(Key const& key, Value const& value);
};
(我一般讓這些公共的,沒有任何理由通過 禁止其使用的客戶端。)
然後,定義operator[]
返回一個代理,具體如下:
template <typename Key, typename Value>
class HashTable
{
public:
class Proxy
{
HashTable* myOwner;
Key myKey;
public:
Proxy(HashTable* owner, Key const& key)
: myOwner(owner)
, myKey(key)
{
}
operator Value const&() const
{
Value const* result = myOwner->get(myKey);
if (result == NULL) {
// Desired error behavior here...
}
return *result;
}
Proxy const& operator==(Value const& value) const
{
myOwner->set(myKey, value);
return *this;
}
};
Value* get(Key const& key) const;
void set(Key const& key, Value const& value);
Proxy operator[](Key const& key)
{
return Proxy(this, key);
}
};
因此,當你寫:
hashTable[key] = newString;
,代理的operator=
將調用hashTable.put(key, newString)
;在其他情況下 ,但是,它會調用隱式類型轉換上 代理,這就要求hashTable.get(key)
。
在某些情況下,即使你渴望返回默認值,它可能是 最好使用此解決方案:get
功能不需要 插入任何物件哈希表,因此該表不填寫了 所有失誤的,你可以在超載的const
operator[]
,所以 你可以用它在const
哈希表也是如此。此外,它不需要 要求值類型具有默認構造函數。
它有相對於在標準 所使用的溶液中的一種缺點;因爲你不能超載operator.
,你不能讓代理 表現得像一個參考,事情就是這樣:
hashTable[string].someFunction();
不起作用。一個解決辦法是在代理過載operator->
,但 這導致有些不自然的語法:
hashTable[string]->someFunction(); // But the hash table contains
// values, not pointers!!!
(不要被隱式轉換爲參考誤導的 隱式轉換不會在表達 a.b
)
我個人不明白問題出在哪裏考慮
a
...(也可以說是雖然) –你要2個不同的返回類型?一個重載的operator []返回一個字符串,另一個重載返回一個向量? –
sashang
從你寫的內容來看,你不清楚每個鍵是否有一個或多個字符串。 –