用泛型类专门化模板函数

Specializing a template function with a generic class

本文关键字:函数 专门化 泛型类      更新时间:2023-10-16

我正在编写一个简单的数据到XML序列化程序,用于培训目的。其想法是将值传递给序列化函数,该函数将执行某些操作,将给定的值转换为字符串格式。许多类型确实有内置的转换,但对于许多类型,我希望有一个专门的函数来实现这一点。我的方法是:

我有一个带有此签名的模板函数:

template <class T> void serialize(T *value, Serializer *serializer);

我可以像这样专门化模板:

template <> void serialize<bool>(bool *value, Serializer *serializer);

工作良好。现在我想为向量编写一个序列化函数,如下所示:

template <class T> void serialize<std::vector<T*> >(std::vector<T*> *value, Serializer *serializer) {
    serializer->begin_section("array");
    for(std::vector<T*>::iterator it = value->begin(); it != value->end(); it++) {
        serializer->add_value(*it);
    }
    serializer->end_section();
}

但当我编译它(g++4.6.2)时,我得到了error: function template partial specialization ‘serialize<std::vector<T*> >’ is not allowed。有什么办法我能做到这一点吗?

您的问题是希望提供一个作为模板本身的模板专用化。

解决问题的最简单方法是根本不使用模板专门化,而是依赖于函数重载。

template<class T> void serialize(T *value, Serializer *serializer);

仍然可以提供默认的实现,但如果像这样的更专业的版本

void serialize(bool *value, Serializer *serializer);

存在时,它将被过载解决方案所优先。这允许您简单地定义一个类似的函数

template <typename T> void serialize(::std::vector<T> *value, Serializer *serializer);

这将被称为矢量。(考虑一下:std::vector比T更专业,所以重载解析会在可能的地方选择这个函数)。

您可以重载serialize(),例如:

#include <iostream>
#include <vector>
template <class T> void serialize(T *, char *)
{
    std::cout << "Tn";
}
template <class T> void serialize(std::vector<T*> *, char *)
{
    std::cout << "vectorn";
}
int main()
{
    int a = 1;
    std::vector<int*> x;
    serialize(&a, 0);
    serialize(&x, 0);
    return 0;
}

输出:

T
vector