2011-11-07 69 views
2

有沒有什麼辦法讓這樣的工作:模板函數接受類似的任何類型的映射<X, Y>

template<typename T, typename X, typename Y> 
void myFunc(T<X,Y> map, X x, Y y) { 
    map[x] += y; 
} 

基本上我想要什麼,就像一個map<X,Y>是有效的輸入。

這可能嗎?

我得到這個錯誤,但我不知道這意味着什麼:

test.cpp:2:17: error: ‘T’ is not a template

+0

爲什麼不只是'template void myFunc(std :: map map){...}'? –

+0

@Oli Charlesworth - 因爲我想讓我的函數接受'map ','unordered_map ','concurrent_hash_map '等 –

+0

也許比我過於廣泛的答案稍微更有語義的方法是檢查是否存在'key_type'和'mapped_type'成員類型。這可以通過特質檢查來完成。另一方面,方括號運算符真的很特別,只存在極少的數據結構... –

回答

4

是,與模板模板模板參數:

template <template <typename, typename> class M, typename K, typename V> 
void Foo(M<K, V> & container) 
{ 
    // ... 
}; 

注意,這絕不會匹配任何真正的字容器,但是,因爲那些有更多的模板參數。與variadics更好:

template <template <typename, typename, typename...> class M, typename K, typename V, typename ...Args> 
void Foo(M<K, V, Args...> & container) 
{ 
    // ... 
}; 

如果variadics是不是一種選擇,你可以利用自己包裹的一點:

template <typename Container> void FooImpl(Container &); 

template <template <typename, typename> class M, 
      typename K, typename V> 
void Foo(M<K,V> & c) { FooImpl(c); } 

template <template <typename, typename, typename> class M, 
      typename K, typename V, typename A1> 
void Foo(M<K,V,A1> & c) { FooImpl(c); } 

template <template <typename, typename, typename, typename> class M, 
      typename K, typename V, typename A1, typename A2> 
void Foo(M<K,V,A1,A2> & c) { FooImpl(c); } 

// etc. 

僅供參考,std::unordered_map需要五個模板參數(鍵,值,哈希函數對象,等式謂詞,分配器)。 Boost的bimap可能需要更多。

通過使函數成爲包裝類的靜態成員並使實現保持私有狀態,並通過提供單個自由訪問器輔助函數,可以防止濫用最後一個構造。

3

最簡單的方法是僅使用T作爲參數類型。

template<typename T, typename X, typename Y> 
void myFunc(T map, X x, Y y) { 
    map[x] += y; 
} 

請注意,這將允許例如。數組作爲T S(如:T = int*, X = int, Y = int和函數就會將y數組mapx個元素。

如果你想將它縮小地圖,你必須決定什麼根據地圖你,認識的地圖的一種可能性是檢查他們的key_typemapped_type。例如:

template<typename T> 
void myFunc(T map, typename T::key_type x, typename T::mapped_type y) { 

如果你真的想接受任何帶有兩個類型參數(而不是更多),你可以使用模板模板參數然而,我認爲這是一個過分的系統ntactic的區別,除非你計劃用多個參數類型實例化template-template參數,否則你不應該使用它。

+0

Doh。應該想到這一點。 –

1

如果不限制的地圖是T型的,事情就變得簡單多了:

template<typename T, typename X, typename Y> 
void myFunc(T map, X x, Y y) { 
    map[x] += y; 
} 

// ... 

map<int, int> myMap; 
myFunc(myMap, 5, 7); 

的std ::地圖實際上已經不僅僅是K和V多個參數(它有一個比較器和一個分配器),所以最好不要匹配它的模板參數。上面的代碼仍然只爲具有非const操作符[]的事物編譯,該操作符將X作爲關鍵字並將Y作爲值返回,但對於非特定Container的容器也是靈活的,例如Container 。

相關問題