2012-03-14 70 views
3

为了训练目的,我正在向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。有什么办法可以做到这一点?

回答

2

你的问题是你想提供一个模板本身的模板专门化。

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

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更专门,所以重载解析会在可能的地方选择这个函数)。

1

你可以重载serialize()for example

#include <iostream> 
#include <vector> 

template <class T> void serialize(T *, char *) 
{ 
    std::cout << "T\n"; 
} 

template <class T> void serialize(std::vector<T*> *, char *) 
{ 
    std::cout << "vector\n"; 
} 

int main() 
{ 
    int a = 1; 
    std::vector<int*> x; 

    serialize(&a, 0); 
    serialize(&x, 0); 

    return 0; 
} 

输出:

T 
vector