2011-06-15 67 views
6

我嘗試使用(僅)STL創建BidirectionalMap類(不,boost不是一個選項)。我有99%的工作方式符合我的要求,但我真的無法弄清楚如何強制模板需要兩種不同的類型,以便可以正確覆蓋operator []。像...執行不同的C++模板參數

template < class KeyType, class ValueType > 
class BidirectionalMap 
{ 
    public: 

    ... 

    const ValueType& operator[](const KeyType& _k) { return(m_keyMap[ _k ]); } 
    const KeyType& operator[](const ValueType& _v) { return(m_valMap[ _v ]); } 

    private: 

    std::map<KeyType> m_keyMap; 
    std::map<ValueType> m_valueMap; 
}; 

main() 
{ 
    BidirectionalMap< Foo, Foo > fooMap; // won't work, ambiguous. 
    BidirectionalMap< Foo, Bar > fooBarMap; // does work. 
} 

想法? -R

+1

C++不會爲你處理這個開箱即用的問題嗎?既然你的'operator' []'會很好,我猜如果'KeyType'和'ValueType'相等,編譯就會失敗。 – larsmoa 2011-06-15 12:25:20

+0

你可以看一下'boost :: multi_index_container'的源代碼來獲得我想的一些提示。如果不符合許可證要求,您不能合法地複製代碼,但您至少可以看到他們是如何做到的。 – 2011-06-15 12:26:00

+1

它已經需要不同的類型。爲這兩個參數提供相同的類型將嘗試創建同一個方法'operator []'的兩個不同版本,從而無法編譯。你還想做什麼? – Xion 2011-06-15 12:26:59

回答

15

只需添加以下部分特:

template <typename T> 
class BidirectionalMap<T, T>; 

這將情況下,編譯來實例化沒有定義(因爲上述只聲明)的模板和吊環如果用戶試圖傳遞與兩個模板參數相同的類型。

+3

請務必在該聲明下方提供有用的評論,向用戶解釋他們做錯了什麼。這實質上是他們的錯誤信息。 – 2011-06-15 12:26:39

+1

或者可能是一個帶有static_assert的實現。 – juanchopanza 2011-06-15 12:37:02

+0

是的,把一個基本的構造函數與'false'的靜態斷言和一個合適的錯誤信息... – 2011-06-15 12:43:18

6

當然真正的問題是:爲什麼這樣的任意限制?

我認爲完全正常的擁有與鍵和值相同的類型,所以不是提供一個模糊的運算符重載,也許可以簡單地提供兩種不同的方法?

ValueType const& by_key(KeyType const&) const; 
KeyType const& by_value(ValueType const&) const; 

並且完成它。

編輯:繼@Georg Fritzsche也此言:)

記住,超載的最重要的規則之一是,所有重載應該有相同的基本含義。

+0

我更喜歡一個類似於這樣的解決方案 - 它不僅限制性較少,而且在閱讀/調試(「等待,那個臨時類型是什麼?」)。 – 2011-06-15 13:39:11

+1

@Georg:的確,我已經編輯了答案,以便將其明確。所有重載應該具有相同的含義/執行(大致)相同的操作,否則讀者很難理解正在發生的事情。 – 2011-06-15 14:19:36