Частичная специализация шаблона на классе - PullRequest
2 голосов
/ 16 сентября 2009

Я ищу лучший способ для этого. У меня есть кусок кода, который должен обрабатывать несколько разных объектов, которые содержат разные типы. Структура, которая у меня есть, выглядит следующим образом:

class Base
{
    // some generic methods
}

template <typename T> class TypedBase : public Base
{
    // common code with template specialization
    private:
        std::map<int,T> mapContainingSomeDataOfTypeT;
}
template <> class TypedBase<std::string> : public Base
{
    // common code with template specialization
    public:
        void set( std::string ); // functions not needed for other types
        std::string get();
    private:
        std::map<int,std::string> mapContainingSomeDataOfTypeT;
        // some data not needed for other types
}

Теперь мне нужно добавить некоторые дополнительные функции, которые применяются только к одному из производных классов. В частности, вывод std :: string, но тип на самом деле не имеет значения. Класс достаточно большой, и я бы предпочел не копировать все это, а просто специализировать небольшую его часть Мне нужно добавить пару функций (и аксессор и модификатор) и изменить тело некоторых других функций. Есть ли лучший способ сделать это?

Ответы [ 2 ]

4 голосов
/ 16 сентября 2009

Вам не нужно специализировать весь класс, только то, что вы хотите. Работает с GCC & MSVC:

#include <string>
#include <iostream>

class Base {};

template <typename T>
class TypedBase : public Base
{
public:
    T get();
    void set(T t);
};

// Non-specialized member function #1
template <typename T>
T TypedBase<T>::get() 
{
   return T();
}

// Non-specialized member function #2
template <typename T>
void TypedBase<T>::set(T t) 
{
    // Do whatever here
}

// Specialized member function
template <>
std::string TypedBase<std::string>::get() 
{
    return "Hello, world!";
}

int main(int argc, char** argv) 
{
    TypedBase<std::string> obj1;
    TypedBase<double> obj2;
    std::cout << obj1.get() << std::endl;
    std::cout << obj2.get() << std::endl;
}
4 голосов
/ 16 сентября 2009

Ввести еще один уровень косвенности в определениях шаблонов:

class Base
{
    // Generic, non-type-specific code
};

template <typename T> class TypedRealBase : public Base
{
     // common code for template
};

template <typename T> class TypedBase : public TypedRealBase<T>
{
    // Inherit all the template functionality from TypedRealBase
    // nothing more needed here
};

template <> class TypedBase<std::string> : public TypedRealBase<T>
{
    // Inherit all the template functionality from TypedRealBase
    // string-specific stuff here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...