Curiously Recurring Template Pattern
Encyclopedia
The curiously recurring template pattern (CRTP) is a C++
idiom in which a class
, who had observed it in some of the earliest C++
template code.
Some use cases for this pattern are static polymorphism, and other metaprogramming techniques such as those described by Andrei Alexandrescu
in Modern C++ Design
.
in the case of multiple inheritance
e.g.:
This technique achieves a similar effect to the use of virtual functions, without the costs (and some flexibility) of dynamic polymorphism. This particular use of the CRTP has been called "simulated dynamic binding" by some. This pattern is used extensively in the Windows ATL
and WTL libraries.
To elaborate on the above example, consider a base class with no virtual functions. Whenever the base class calls another member function, it will always call its own base class functions. When we derive a class from this base class, we inherit all the member variables and member functions that weren't overridden (no constructors or destructors). If the derived class calls an inherited function that then calls another member function, that function will never call any derived or overridden member functions in the derived class.
However, if base class member functions use CRTP for all member function calls, the overridden functions in the derived class will be selected at compile time. This effectively emulates the virtual function call system at compile time without the costs in size or function call overhead (VTBL structures, and method lookups, multiple-inheritance VTBL machinery) at the disadvantage of not being able to make this choice at runtime.
Each time an object of class
This allows obtaining copies of squares, circles or any other shapes by shapePtr->clone.
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
idiom in which a class
X
derives from a class template instantiation using X
itself as template argument. The name of this idiom was coined by Jim CoplienJim Coplien
James O. "Jim" Coplien is a writer, lecturer, and researcher in the field of Computer Science. He has made key contributions in the areas of software design, organizational development, software debugging, and in empirical research...
, who had observed it in some of the earliest C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
template code.
General form
Some use cases for this pattern are static polymorphism, and other metaprogramming techniques such as those described by Andrei Alexandrescu
Andrei Alexandrescu
Andrei Alexandrescu is a Romanian C++ programmer and author. He is particularly known for his pioneering work on policy-based design implemented via template metaprogramming. These ideas are articulated in his book Modern C++ Design and were first implemented in his programming library, Loki. He...
in Modern C++ Design
Modern C++ Design
Modern C++ Design: Generic Programming and Design Patterns Applied is a book written by Andrei Alexandrescu, published in 2001 by Addison-Wesley. It has been regarded as "one of the most important C++ books" by Scott Meyers ....
.
Static polymorphism
Typically, the base class template will take advantage of the fact that member function bodies (definitions) are not instantiated until long after their declarations, and will use members of the derived class within its own member functions, via the use of a castType conversion
In computer science, type conversion, typecasting, and coercion are different ways of, implicitly or explicitly, changing an entity of one data type into another. This is done to take advantage of certain features of type hierarchies or type representations...
in the case of multiple inheritance
Multiple inheritance
Multiple inheritance is a feature of some object-oriented computer programming languages in which a class can inherit behaviors and features from more than one superclass....
e.g.:
This technique achieves a similar effect to the use of virtual functions, without the costs (and some flexibility) of dynamic polymorphism. This particular use of the CRTP has been called "simulated dynamic binding" by some. This pattern is used extensively in the Windows ATL
Active Template Library
The Active Template Library is a set of template-based C++ classes developed by Microsoft, intended to simplify the programming of Component Object Model objects. The COM support in Microsoft Visual C++ allows developers to create a variety of COM objects, OLE Automation servers, and ActiveX...
and WTL libraries.
To elaborate on the above example, consider a base class with no virtual functions. Whenever the base class calls another member function, it will always call its own base class functions. When we derive a class from this base class, we inherit all the member variables and member functions that weren't overridden (no constructors or destructors). If the derived class calls an inherited function that then calls another member function, that function will never call any derived or overridden member functions in the derived class.
However, if base class member functions use CRTP for all member function calls, the overridden functions in the derived class will be selected at compile time. This effectively emulates the virtual function call system at compile time without the costs in size or function call overhead (VTBL structures, and method lookups, multiple-inheritance VTBL machinery) at the disadvantage of not being able to make this choice at runtime.
Object counter
The main purpose of an object counter is retrieving statistics of object creation and destruction for a given class. This can be easily solved using CRTP:Each time an object of class
X
is created, the constructor of counter
is called, incrementing both the created and alive count. Each time an object of class X
is destroyed, the alive count is decremented. It is important to note that counter
and counter
are two separate classes and this is why they will keep separate counts of X
's and Y
's. In this example of CRTP, this distinction of classes is the only use of the template parameter (T
in counter
) and the reason why we cannot use a simple un-templated base class.Polymorphic copy construction
When using polymorphism, one quite often needs to create copies of objects by the base class pointer. A commonly used idiom for this is adding a virtual clone function that is defined in every derived class. The CRTP pattern can be used to avoid having to duplicate that function or other similar functions in every derived class.This allows obtaining copies of squares, circles or any other shapes by shapePtr->clone.