Шаблонная специализация и наследование
Предположим, что у меня есть класс шаблонов с множеством функций, и я хочу специализировать их, чтобы изменить только некоторые из них, и сохранить остальные в точности так, как указано в базовом шаблоне.
Как я могу это сделать?
Ниже я хочу достичь, но решение не очень хорошо, потому что это не позволяет мне ссылаться на специализацию для int
как Base<int>
– Мне нужно использовать IntSpec
для этого.
#include <iostream>
using namespace std;
template<typename T>
struct Base
{
void print1() {cout << "Base::print1" << endl;};
void print2() {cout << "Base::print2" << endl;};
};
struct IntSpec : public Base<int>
{
void print2() {cout << "Base<int>::print2()" << endl;};
};
int main()
{
Base<double> d;
// Base<int> i; <-- I want this kind of instantiation
IntSpec i;
d.print1();
d.print2();
i.print1();
i.print2();
}
Вывод:
Base::print1
Base::print2
Base::print1
Base<int>::print2()
Ответы
Ответ 1
Решение Nicol отлично работает, но это альтернатива:
template<typename T>
struct Base
{
void print1() {cout << "Base::print1" << endl;};
void print2() {cout << "Base::print2" << endl;};
};
template<>
void Base<int>::print2() {cout << "Base<int>::print2()" << endl;};
Таким образом, вы можете специализировать только определенные функции-члены и по-прежнему использовать те, которые вы не специализировали (в данном случае, print1
) без каких-либо проблем. Итак, теперь вы будете использовать его так, как хотите:
Base<int> i;
i.print1();
i.print2(); // calls your specialization
Демо здесь.
Ответ 2
Вам просто нужно использовать два класса шаблонов:
template<typename T>
struct CommonBase
{
void print1() {cout << "Base::print1" << endl;};
void print2() {cout << "Base::print2" << endl;};
};
template<typename T>
struct Base : public CommonBase<T>
{
};
template<>
struct Base<int> : public CommonBase<int>
{
void print2() {cout << "Base::print2" << endl;};
};
Вы всегда используете Base
, а не CommonBase
.
Ответ 3
Другим решением было бы добавить уровень косвенности в функции, которую вы хотите переопределить, т.е.
template<typename T>
struct foo
{
template<typename T2>
void bar_impl()
{
//generic function
}
void bar()
{
bar_impl<T>();
}
};
Затем вы можете специализировать каждую функцию по отдельности для каждого типа или специализировать весь тип по желанию.