2011-10-11 141 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) 
{ 
    // ... 
}