Ответ
Да, но с важными ограничениями.
В C++ виртуальный метод не может быть шаблоном функции (function template). Однако метод шаблонного класса может быть виртуальным. Разница ключевая:
- НЕЛЬЗЯ: Объявить виртуальный метод, который сам является шаблоном с параметром
typename T. - МОЖНО: Объявить виртуальный метод внутри шаблонного класса. При этом виртуальность работает для конкретной инстанциации (специализации) этого класса.
Пример корректного использования (виртуальный метод в шаблонном классе):
template <typename T>
class Processor {
public:
// Виртуальный метод шаблонного класса.
// Для каждой специализации Processor<int>, Processor<double> и т.д.
// создается своя виртуальная таблица.
virtual void process(const T& value) {
std::cout << "Base processing: " << value << 'n';
}
virtual ~Processor() = default;
};
class IntProcessor : public Processor<int> {
public:
// Переопределение виртуального метода для специализации Processor<int>
void process(const int& value) override {
std::cout << "IntProcessor: " << value * 2 << 'n';
}
};
int main() {
Processor<int>* p = new IntProcessor();
p->process(5); // Вывод: IntProcessor: 10
delete p;
}
Пример, который вызовет ошибку компиляции:
class InvalidBase {
public:
// ОШИБКА: виртуальный метод не может быть шаблоном функции.
template <typename T>
virtual void templateMethod(T arg) {}
};
Почему такое ограничение? Механизм виртуальных вызовов (vtable) требует, чтобы сигнатура метода (включая тип возвращаемого значения) была известна на этапе компиляции для построения таблицы. Шаблон функции инстанцируется в разные типы методов в процессе компиляции, что делает невозможным создание единой таблицы для всех возможных инстанциаций.