Templates and generic programming
T.80
Не шаблонизируйте иерархию классов без необходимости
Причина
Шаблонизация иерархии классов, содержащей множество функций, особенно виртуальных, может привести к раздуванию кода.
Пример (плохой)
template<typename T>
struct Container { // интерфейс
virtual T* get(int i);
virtual T* first();
virtual T* next();
virtual void sort();
};
template<typename T>
class Vector : public Container<T> {
public:
// ...
};
Vector<int> vi;
Vector<string> vs;
Определять sort как функцию-член контейнера, вероятно, плохая идея, но это не беспрецедентно, и это хороший пример того, чего не следует делать.
Учитывая это, компилятор не знает, будет ли вызвана vector<int>::sort(), поэтому он должен сгенерировать для неё код. Аналогично для vector<string>::sort(). Если эти две функции никогда не вызываются — это лишний код. Представьте, что произойдёт с иерархией классов, содержащей десятки функций-членов и десятки производных классов со множеством инстанциаций.
Примечание
Во многих случаях можно обеспечить стабильный интерфейс, не параметризуя базовый класс; см. «стабильная база» и ОО и ОП
Контроль
- Помечать виртуальные функции, зависящие от аргумента шаблона. ??? Ложные срабатывания