Введение
Узоры разработки программного обеспечения (Software design pattern) Узоры любопытно повторяющихся шаблонов (CRTP) - это идиом, изначально написанный на C++, в котором класс X получается из инстанцирования шаблона класса, используя сам X в качестве аргумента шаблона. Более широко это известно как F-связанный полиморфизм, и это форма F-связанного количественного определения.
The curiously recurring template pattern (CRTP) is an idiom, originally in C++, in which a class X derives from a class template instantiation using X itself as a template argument. More generally it is known as F bound polymorphism, and it is a form of F bounded quantification.
История
Метод был официально утвержден в 1989 году как "F-ограниченное количественное определение". Название "CRTP" было независимо придумано Джимом Коплиеном в 1995 году, который наблюдал его в некоторых из самых ранних шаблонов C ++, а также в примерах кода, которые Тимоти Бадд создал в своем многопарадигматическом языке Leda. Иногда его называют "Верхняя Наследие" из-за того, что он позволяет расширять иерархию классов путем замены различных базовых классов. Microsoft Implementation of CRTP in Active Template Library (ATL) была независимо открыта, также в 1995 году, Яном Фалькиным, который случайно вывел базовый класс из выведенного класса. Кристиан Бомонт впервые увидел код Яна и сначала подумал, что он не может быть скомпилирован в компиляторе Microsoft, доступном в то время. После того, как стало известно, что это действительно работает, Кристиан основал весь дизайн ATL и Windows Template Library (WTL) на этой ошибке.
as well as in code examples that Timothy Budd created in his multiparadigm language Leda. It is sometimes called "Upside Down Inheritance" due to the way it allows class hierarchies to be extended by substituting different base classes. The Microsoft Implementation of CRTP in Active Template Library (ATL) was independently discovered, also in 1995, by Jan Falkin, who accidentally derived a base class from a derived class. Christian Beaumont first saw Jan's code and initially thought it could not possibly compile in the Microsoft compiler available at the time. Following the revelation that it did indeed work, Christian based the entire ATL and Windows Template Library (WTL) design on this mistake.
Недостатки
Одна проблема с статическим полиморфизмом заключается в том, что без использования общего базового класса, такого как AbstractShape из приведенного выше примера, производное класса не может храниться однородно, то есть помещать различные типы, полученные из одного базового класса, в один и тот же контейнер. Например, контейнер, определенный как std::vector<Shape*>, не работает, потому что Shape - это не класс, а шаблон, нуждающийся в специализации. Контейнер, определенный как std::vector<Shape<Circle>*>, может хранить только круги, а не квадраты. Это связано с тем, что каждый из классов, полученных из базового класса CRTP Shape, является уникальным типом. Общее решение этой проблемы - унаследовать от общего базового класса с виртуальным деструктором, как в примере AbstractShape выше, что позволяет создать std:: vector<AbstractShape*>.