Не перепараметризуйте члены (SCARY)
Причина
Член, не зависящий от параметра шаблона, не может использоваться иначе как для конкретного аргумента шаблона. Это ограничивает применение и, как правило, увеличивает размер кода.
Пример (плохой)
template<typename T, typename A = std::allocator<T>>
// requires Regular<T> && Allocator<A>
class List {
public:
struct Link { // не зависит от A
T elem;
Link* pre;
Link* suc;
};
using iterator = Link*;
iterator first() const { return head; }
// ...
private:
Link* head;
};
List<int> lst1;
List<int, My_allocator> lst2;
Выглядит невинно, но теперь Link формально зависит от аллокатора (даже несмотря на то что не использует его). Это вынуждает к избыточным инстанциям, которые могут быть неожиданно дорогостоящими в ряде реальных сценариев. Как правило, решением является вынесение того, что было бы вложенным классом, за пределы класса с собственным минимальным набором параметров шаблона.
template<typename T>
struct Link {
T elem;
Link* pre;
Link* suc;
};
template<typename T, typename A = std::allocator<T>>
// requires Regular<T> && Allocator<A>
class List2 {
public:
using iterator = Link<T>*;
iterator first() const { return head; }
// ...
private:
Link<T>* head;
};
List2<int> lst1;
List2<int, My_allocator> lst2;
Некоторых пугала мысль о том, что Link больше не скрыт внутри списка, поэтому техника получила название SCARY. Из той академической статьи: «Аббревиатура SCARY описывает присваивания и инициализации, которые кажутся ошибочными (Seemingly erroneous — appearing Constrained by conflicting generic parameters), но на самом деле работают при правильной реализации (Actually work with the Right implementation — unconstrained bY the conflict due to minimized dependencies)».
Примечание
Это также распространяется на лямбды, которые не зависят от всех параметров шаблона.
Контроль
- Помечать типы-члены, не зависящие от каждого параметра шаблона
- Помечать функции-члены, не зависящие от каждого параметра шаблона
- Помечать лямбды или переменные-шаблоны, не зависящие от каждого параметра шаблона