2012-03-08 100 views
1

我用模板寫了類。類具有map成員和一些getxxx()/ setxxx()成員函數。我想在C++中爲map <>返回給定KEY的VALUE值。在地圖<>中不存在KEY的情況下返回什麼?

template<typename T1,typename T2> 
class C1{ 
    map<T1,T2> M; 
public: 
    map<T1,T2> getM(); 
    T2 getMvalue(T1 Key); 
    void setM(T1 key,T2 Value); 
}; 

這裏我想實現getMvalue(),它臨危鍵作爲參數,並返回相應的「值」,如果「鑰匙」是MAPM可用。

它看起來像......

template<typename TKey,typename TValue> 
T2 C1<T1,T2>::getMvalue(T1 Key){ 
    if(M.count(Key)>0) 
     return M[Key]; 
    else 
     return(???); 
}; 

在這裏,我需要的地方???中使用的東西。記住函數的返回類型是T2,根據用戶的決定可以是任何東西。 我如何取代「???」和什麼?

回答

3

我會鼓勵你使用TryGet模式

template<typename TKey,typename TValue> 
bool C1<T1,T2>::tryGetMvalue(T1 key, T2& value){ 
    if(M.count(key)>0) { 
     value = objProperties[key]; 
     return true; 
    } 
    return false; 
}; 
+0

這就是我正在建議你何時擊敗我的過程...... +1 – tmpearce 2012-03-08 17:58:18

+0

地圖<>中會有數百個鍵值對,並且會有數千個這樣的類對象。 因此,當在每個對象的地圖<>中搜索KEY時,將具有更高的時間複雜度。 在這種情況下,使用這種技術會更好(使用tryGet),如果KEY存在,將需要「兩次」搜索。 – 2012-03-08 18:04:59

+0

@NDThokare:你可以使用'find()'而不是'count()'和'[]'組合。那麼只會有一個搜索。 – 2012-03-08 18:11:40

2

您的選擇有三個:

  1. throw異常
  2. 修改簽名,以便您可以返回數據帶外的(這是什麼@JaredParsuggests
  3. 返回帶內數據。 3引線

    template<typename TKey,typename TValue> 
        T2 C1<T1,T2>::getMvalue(T1 Key){ 
        if(M.count(Key)>0) 
         return M[Key]; 
        else 
         return T2(); 
        }; 
    

    當心,設計選擇#到錯誤:

如果必須選3,我將返回默認值(這是std::map::operator[]一樣)。來電者無法區分「標稱值」和「不存在」。


P.s.如果你返回默認值,那麼你的代碼可能簡化爲:

template<typename TKey,typename TValue> 
T2 C1<T1,T2>::getMvalue(T1 Key){ 
    return M[key]; 
} 
+0

在第二種情況下, operator []:返回對使用鍵值的元素的值的引用,如果它還不存在,則使用鍵插入元素。這是我想避免的。 – 2012-03-08 18:16:51

2

使用operator[],你已經限制自己只保存默認constructible值;所以你可以返回TKey() - 除非用戶需要分辨是否真的找到它。

如果你不希望這樣的限制,那麼你就必須改變它的東西,如:

auto found = map.find(key); 
if (found != map.end()) { 
    return found->second; 
} else { 
    return ???; 
} 

現在最簡單的方法來表示失敗是返回類型更改爲指針(或也許boost::optional如果你想返回值),並返回null(或boost::none);或通過引用參數返回結果並用布爾返回值指示成功;或拋出異常。

+0

喜歡'boost :: optional'超過指針的任何理由?如果函數計算一個值,並且必須返回一個右值,類似'boost :: optional'(但名稱更好)是理想的,但是當你保證左值時,指針似乎更簡單(至少對我來說)。 – 2012-03-08 18:03:31

+0

@JamesKanze:不是特別的;我只是想我會提到它。在類似的情況下,你需要返回一個本地對象,所以不能返回一個指針。 – 2012-03-08 18:07:08

+0

它肯定會成爲本週結束。我剛剛看到'boost :: optional'突出顯示,並且錯過了你也提出了一個指針的事實。 (我同意這一點值得一提,雖然這個名字很難適用於這種情況,但在Boost之前我們大多數人已經在我們的工具包中有一個更好的替代方案)。 – 2012-03-08 18:13:39

1

幾種可能性。最簡單的方法是讓getter返回一個 指針,如果該鍵不在地圖中,則返回空指針。 或者,你可以讓它返回一個Fallible(或者可能,或者不管你稱之爲什麼)或者 ;而一般的好的解決方案,似乎在 這裏矯枉過正。或者最後,如果 對象不存在,則可以簡單地拋出異常。

相關問題