#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
};
В зависимости от конкретных деталей вашего шаблонного класса должен работать тот или иной подход; или какая-то вариация на ту же тему.