Специализация шаблонной функции с универсальным классом - PullRequest
3 голосов
/ 14 марта 2012

Я пишу простые данные в 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 ]

2 голосов
/ 14 марта 2012

Ваша проблема в том, что вы хотите предоставить специализацию шаблона, которая является самим шаблоном.

Самый простой способ решения вашей проблемы - вообще не использовать специализацию шаблона и вместо этого полагаться на перегрузку функций.

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 голос
/ 14 марта 2012

Вы можете перегрузить serialize(), , например :

#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
...