2011-10-11 139 views
2

好吧,所以我只是學習模板。不管怎麼說,我可能(最絕)做錯了,但這裏的問題:C++模板函數特化 - 模板參數數量錯誤?

我的第一個模板函數聲明如下:

template<typename T> 
std::ostream& printFormatted(T const& container, std::ostream& os = std::cout) { 
    //... 
} 

然後我應該實現一個專門的案例地圖,所以這就是我試圖做的:

template<> 
std::ostream& printFormatted<std::map<typename key, typename value>>(std::map<typename key, typename value> const& container, std::ostream& os = std::cout) { 
    //... 
} 

我可能會做出與我的鍵/值的變量,不知道,但無論一個錯誤,試圖編譯我得到的錯誤消息時:

error: wrong number of template arguments (1, should be 4) 
error: provided for ‘template<class _Key, class _Tp, class _Compare, class _Allocator> class std::__debug::map’ 

顯然有一些我不明白的模板或地圖?有人請幫忙?

+0

是'key'和'value'實際類型的代碼或者你打算在他們的佔位符? –

回答

3

假設你的keyvalue用途意思是placeholers,你不能用關鍵字typename在線聲明模板參數。也就是說,Foo<typename T>始終是無效的,但不會被誤認爲Foo<typename T::bar>,這是完全不同的。專業化的語法如下:

// Declare template parameters up front 
template<typename Key, typename Value> 
std::ostream& 
printFormatted<std::map<Key, Value> >(std::map<Key, Value> const& container, std::ostream& os = std::cout); 

但是這是行不通的,因爲它是一個部分專業化和那些不允許函數模板。使用重載代替:

template<typename Key, typename Value> 
std::ostream& 
printFormatted(std::map<Key, Value> const& container, std::ostream& os = std::cout); 

此重載將優於較一般的模板。

+2

只有匹配'less '和'std :: allocator'的地圖,儘管如此:-( –

+0

謝謝,這個問題解決得很好! – Fault

0

這個答案是不相關的C++ 11

如果您使用的是預C++編譯器11,關閉嵌套模板時不能使用>>。您需要>之間的空間。

C++將>>看作與>不同的令牌,並且編譯器不使用它來關閉模板。您需要一個空間,以便編譯器看到一個>後跟一個>

以下是更可能的工作:

template<> 
std::ostream& printFormatted<std::map<typename key, typename value> >(std::map<typename   key, typename value> const& container, std::ostream& os = std::cout) { 
    //... 
} 
+0

這實際上是用C++ 0x/C++修復的11 – Fault

+0

太棒了!我沒有聽說過,當我剛剛啓動C++時,它讓我瘋狂。我將留下這個答案,以幫助任何人使用舊的編譯器,但編輯它來澄清這一點。 – Dan

+0

即使我發現'>>'空格更具可讀性! –

3

你在做什麼不是完全專業化,但部分專精,因爲你仍然有一個模板,只有一個更專業化。但是,你不能部分地專門化函數,所以我們只是提供一個新的過載。對於std::map,需要四個模板參數(如錯誤消息有益告訴你):

template <typename K, typename V, typename Comp, typename Alloc> 
std::ostream & printFormatted(const std::map<K,V,Comp,Alloc> & m, 
           std::ostream & o = std::cout) 
{ 
    // ... 
}