Content deleted Content added
No edit summary |
|||
Line 1:
The '''curiously recurring template pattern''' ('''CRTP''') is a [[C++]] idiom in which a class <code>X</code> derives from a class template instantiation using <code>X</code> itself as template argument. The name of this idiom was coined by Coplien{{ref|Coplien}}, who had observed it in some of the earliest [[C++]] template code.
==
<source lang="cpp">
// The Curiously Recurring Template Pattern (CRTP)
template <typename derived>
struct base
{
// ...
};
struct derived : base<derived>
{
Line 9 ⟶ 15:
};
</source>
Some use cases for this pattern are <code>static polymorphism</code> (see [[Template_metaprogramming]]) and other metaprogramming techniques as those described by Alexandrescu{{ref|Alexandrescu}} in [[Modern C++ Design]].
== 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 <code>static_cast</code>, or simply a cast e.g.:
Line 42 ⟶ 52:
However, if base class member functions use the CRTP pattern for all member function calls, the overridden functions in the derived class will get 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) and the slight disadvantage of not being able to do 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:
<source lang="cpp">
template <typename T>
struct counter
{
counter()
{
objects_created++;
objects_alive++;
}
virtual ~counter()
{
--objects_alive;
}
static int objects_created;
static int objects_alive;
};
template <typename T> unsigned long counter<T>::objects_created( 0 );
template <typename T> unsigned long counter<T>::objects_alive( 0 );
class X : counter<X>
{
// ...
};
class Y : counter<Y>
{
// ...
};
</source>
Each time an object of class <code>X</code> is created, the constructor of <code>counter<X></code> is called, incrementing both the created and alive count. Each time an object of class <code>X</code> is destroyed, the alive count is decremented. In this example, none of the functionality in the template uses the template parameter, and it is only used as a way of creating different static counters for different classes. Remember that each instantiation of a template with a type argument is a class of itself, and thus the static counter attributes in the <code>counter</code> template are different offering separated counters for <code>X</code> and <code>Y</code> classes.
==See also==
Line 49 ⟶ 96:
==References==
* {{note|Coplien}}{{cite journal | author=Coplien, James O. | title=Curiously Recurring Template Patterns | journal=C++ Report | year=1995, February | pages=24–27}}
* {{note|Alexandrescu}}[[Andrei Alexandrescu]]: ''[[Modern C++ Design]]: Generic Programming and Design Patterns Applied'', Addison-Wesley, ISBN 3-8266-1347-3
[[Category:Software design patterns]]
|