2011-06-30 78 views
2

我的std ::子類地圖如何爲多個鍵類型專門化一個std映射?

template<class ValueT> 
FancyKeyMap 
    : public std::map<FancyKey,ValueT, FancyKey::Less> 
{ 
    ... 
public: 
    inline iterator find(FancyKeyArg key) 
    { 
     return(std::map<FancyKey,ValueT, 
       FancyKey::Less>::find(FancyKeyArg.makeKeyRef())); 
    } 
}; 

這工作得很好,(不要問我爲什麼不希望使用一些implicint轉換,這會導致太多的曖昧重載也在這種情況下,一個完整的轉換是昂貴的:)

反正它woudl是很好,如果上述可能是性病的專業化::地圖,任何

std::map<FancyKey,ValueT> fancymap; 

woudl做同樣的事情,

FancyKeyMap<ValueT> fancyMap; 

能做這種專業化嗎?


好吧只是嘗試了偏特:

namespace std { 

template<class ValT, class CompareT=FancyKey::Less, 
     class AllocT=allocator<pair<const FancyKey,ValT> > > 
    class map<FancyKey, ValT, CompareT, AllocT> 
{ 
    .... 
}; 

} 

我得到這個錯誤:

「默認參數不允許在局部特殊化」

而是使之像std :: map需要讓「繼承」的默認參數允許它們被覆蓋。下一步是可能的?

我沒有看到一個建議,對於具有搜索模板FAQ它似乎這是一個非常普遍的問題; ^>

+0

爲什麼你有'FancyKeyMap'? – GManNickG

+2

在C++ 0x中,你可以說'tempate 使用FancyKeyMap = std :: map ;'。 –

+2

我希望你知道,從STL容器繼承通常被認爲是不好的做法,因爲它們沒有虛擬析構函數。如果你不添加數據成員到你的班級,你可以避開它,但最好用組合來代替。 –

回答

0

這似乎是一個很大的麻煩,避免打字makeKeyRef()(在find呼叫)和更加明確的意圖在同一時間。你有沒有考慮過只是在做額外的打字工作,並且讓未來的維護者清楚你的意圖?另外,由於標準容器沒有虛擬析構函數,除非你非公開繼承,所以當基類指針有時被銷燬時,你會打開未定義的行爲。

+0

由於子類只包含一個內嵌的參數,析構函數並不是問題。主要目的是這樣編寫代碼,就好像它是一個std :: map並讓它選擇適當的比較引用,並根據鍵類型進行鍵引用強制轉換,然後使用標題來改變集中定義行爲(分解出來)而不必更改所有的代碼。或者如果您同時切換鍵類型。我想要的是可以指定默認比較類型的鍵類型的專門化,並覆蓋一些方法。 – peterk

相關問題