Возможно ли, чтобы специализированная версия разделяла некоторые функции с исходным шаблонным классом?

#c #c 11 #templates #visual-c #template-specialization

#c #c 11 #шаблоны #visual-c #шаблон-специализация

Вопрос:

Возможно ли, чтобы специализированная версия класса разделяла некоторые или все функции исходного шаблонного класса?

т.е. рассмотрим, что существует шаблонный класс,

 template <typename T>
class A
{
    A()
    {}
    A(const Aamp; ref)
    {}
    void f1()
    {
        //do something
    }
    void f2()
    {
        //do something
    }
    void f3()
    {
        //do something
    }
}
 

и у него есть специализированная версия для определенного типа данных, которая предназначена только для добавления некоторых дополнительных функций в общую версию в дополнение к исходным общим функциям.

 template<>
class A<int>
{
    void f4()
    {
        //do something
    }
}
 

теперь я конкретно хочу, чтобы эта специализированная версия использовала все из своей общей версии, включая конструкторы, если это возможно.

Комментарии:

1. Может быть, наследование здесь лучший выбор?

2. Нет, это невозможно так просто, как вы хотите. Имейте это в виду: каждая специализация шаблона представляет собой отдельное определение класса с другим типом (таким образом, name( для компилятора, независимо от того, выглядят ли они для вас с одинаковым именем.

3. На случай, если вы не знаете, можно специализировать отдельные функции шаблона класса, не специализируя весь класс.

Ответ №1:

Обычно это можно реализовать путем реструктуризации иерархии классов:

 template <typename T>
class A_base
{
     // All the f1() functions, et. al, implemented here
};

template<typename T> class A : public A_base<T> {

public:

     // An empty shell of a class, with the constructor
     // forwarding its arguments to the superclass.

     template<typename ...Args> A(Args amp;amp; ...args)
          : A_base(std::forward<Args>(args)...)
     {
     }
};

template<>
class A<int> : public A_base<int>
{
    // Same constructor.

    void f4()
    {
        //do something
    }
};
 

В конечном итоге вы перемещаете все методы класса, члены класса, в базовый класс, при этом ваш шаблонный класс состоит не из чего иного, как производного от шаблона базового класса; и пустой фасад в противном случае.

Затем ваша специализация точно так же происходит от базового класса и добавляет свои собственные методы.

Другой альтернативой является реализация такого рода вывода «задом наперед».

 // Empty template class.

template<typename T> class A_extra {};

// Your specialization, with the extra method:

template<>
class A_extra<int> {

    void f4()
    {
    }
};

// And the template class inherits from it:

template<typename T> class A : public A_extra<T> {

   // Your template class
};
 

В зависимости от конкретных деталей вашего шаблонного класса должен работать тот или иной подход; или какая-то вариация на ту же тему.