模板类部分专用化语法



以下部分模板类专用化的基本示例,取自此维基页面:

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> 的部分专用模板类实例。

您似乎将部分专用化与默认模板参数混淆了。进一步看来,您需要两者(原因未说明,但并不重要)。虽然不完全直观,但可以按如下方式完成:

#include <iostream>
template <typename Key, typename Value = bool>
class KeyValuePair
{
public:
    KeyValuePair()
    {
        std::cout << __PRETTY_FUNCTION__ << ':' << "originaln";
    }
};
template <typename Key>
class KeyValuePair<Key, bool>
{
public:
    KeyValuePair()
    {
        std::cout << __PRETTY_FUNCTION__ << ':' << "specializedn";
    }
};

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

对某些人来说,令人困惑的部分是默认参数规范,但是由于后来的专用化,后面的模板永远不会真正看到该默认参数的结果。在这种情况下,我更喜欢使用默认参数列表转发声明模板。至少对我来说,它使阅读变得稍微容易一些。如果你觉得它提供了清晰度,你可以(或不)选择做同样的事情。像这样:

template <typename Key, typename Value = bool>
class KeyValuePair;
template <typename Key, typename Value>
class KeyValuePair
{
public:
    KeyValuePair()
    {
        std::cout << __PRETTY_FUNCTION__ << ':' << "originaln";
    }
};
template <typename Key>
class KeyValuePair<Key, bool>
{
public:
    KeyValuePair()
    {
        std::cout << __PRETTY_FUNCTION__ << ':' << "specializedn";
    }
};

部分模板专用化不允许忘记模板参数。你必须写:

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;

示例:http://coliru.stacked-crooked.com/a/5095fc5c358d291a

您正确定义了部分专用化,但模板需要 2 个参数,而您只提供一个参数。

您可以使用默认参数:

template <typename Key, typename Value = bool>
class KeyValuePair {};

以允许

KeyValuePair<int> kvpi;

如果需要,您可以保留部分专业化

template <typename Key>
class KeyValuePair<Key, bool> { /* something specific to Value=bool */ };

最新更新