以下从this wiki page获取的部分模板类专门化的基本示例:
template <typename Key, typename Value>
class KeyValuePair { /* something generic */ };
template <typename Key>
class KeyValuePair<Key, bool> { /* something specific to Value=bool */ };
KeyValuePair<int> kvpi;
生成编译器错误:
prog.cpp:10:17: error: wrong number of template arguments (1, should be 2) KeyValuePair<int> kvpi;
为什么?我究竟做错了什么 ? 如何声明和实例化部分模板类专业化?
我希望变量kvpi
是KeyValuePair<int,bool>
类型的部分专用模板类实例。
答案 0 :(得分:4)
您似乎将部分特化与默认模板参数混淆。它似乎你需要两者(原因未说明,但不是很重要)。虽然不完全直观,但可以按如下方式完成:
#include <iostream>
template <typename Key, typename Value = bool>
class KeyValuePair
{
public:
KeyValuePair()
{
std::cout << __PRETTY_FUNCTION__ << ':' << "original\n";
}
};
template <typename Key>
class KeyValuePair<Key, bool>
{
public:
KeyValuePair()
{
std::cout << __PRETTY_FUNCTION__ << ':' << "specialized\n";
}
};
int main()
{
KeyValuePair<int,int> kvp1;
KeyValuePair<int> kvp2;
}
<强>输出强>
KeyValuePair<int, int>::KeyValuePair() [Key = int, Value = int]:original
KeyValuePair<int, bool>::KeyValuePair() [Key = int, Value = bool]:specialized
一些令人困惑的部分是默认的参数规范,但是后面的模板实际上永远不会看到与default-arg的结果,因为后来的特化。在这种情况下,我更喜欢使用其默认参数列表转发声明模板。至少对我而言,它更容易阅读。如果您觉得它提供清晰度,您可以(或不)选择这样做。类似的东西:
template <typename Key, typename Value = bool>
class KeyValuePair;
template <typename Key, typename Value>
class KeyValuePair
{
public:
KeyValuePair()
{
std::cout << __PRETTY_FUNCTION__ << ':' << "original\n";
}
};
template <typename Key>
class KeyValuePair<Key, bool>
{
public:
KeyValuePair()
{
std::cout << __PRETTY_FUNCTION__ << ':' << "specialized\n";
}
};
答案 1 :(得分:4)
部分模板专业化不允许您忘记模板参数。你必须写:
KeyValuePair<int, bool> kvpib;
将使用正确的专业化。
但是你可以使用继承来实现你想要的东西:
template <typename Key>
class KeyBoolPair : public KeyValuePair<Key, bool> {};
KeyBoolPair<int> kbpi;
或者如果您使用C ++ 11或更高版本:
template <typename Key>
using KeyBoolPairBis = KeyValuePair<Key, bool>;
KeyBoolPairBis<int> kbpbi;
答案 2 :(得分:3)
您可以正确定义部分特化,但模板需要2个参数,而您只提供一个参数。
您可以使用默认参数:
template <typename Key, typename Value = bool>
class KeyValuePair {};
允许
KeyValuePair<int> kvpi;
如果需要,您可以保留部分专业化
template <typename Key>
class KeyValuePair<Key, bool> { /* something specific to Value=bool */ };