Curiously recurring template pattern

Curiously recurring template pattern

The curiously recurring template pattern (CRTP) is a C++ 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 Coplien,[1] who had observed it in some of the earliest C++ template code.

Contents

General form

// The Curiously Recurring Template Pattern (CRTP)
template <typename T>
struct base
{
    // ...
};
struct derived : base<derived>
{
    // ...
};

Some use cases for this pattern are static polymorphism, and other metaprogramming techniques such as those described by Andrei Alexandrescu in Modern C++ Design.[2]

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 cast in the case of multiple inheritance e.g.:

template <class Derived> 
struct Base
{
    void interface()
    {
        // ...
        static_cast<Derived*>(this)->implementation();
        // ...
    }
 
    static void static_func()
    {
        // ...
        Derived::static_sub_func();
        // ...
    }
};
 
struct Derived : Base<Derived>
{
    void implementation();
    static void static_sub_func();
};

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.[3] 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.

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:

template <typename T>
struct counter
{
    static int objects_created;
    static int objects_alive;
 
    counter()
    {
        ++objects_created;
        ++objects_alive;
    }
protected:
    ~counter() // objects should never be removed through pointers of this type
    {
        --objects_alive;
    }
};
template <typename T> int counter<T>::objects_created( 0 );
template <typename T> int counter<T>::objects_alive( 0 );
 
class X : counter<X>
{
    // ...
};
 
class Y : counter<Y>
{
    // ...
};

Each time an object of class X is created, the constructor of counter<X> 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<X> and counter<Y> 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<T>) 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.

// Base class has a pure virtual function for cloning
class Shape {
public:
    virtual ~Shape() {}
    virtual Shape *clone() const = 0;
};
// This CRTP class implements clone() for Derived
template <typename Derived> class Shape_CRTP: public Shape {
public:
    Shape *clone() const {
        return new Derived(static_cast<Derived const&>(*this));
    }
};
// Every derived class inherits from Shape_CRTP instead of Shape
class Square: public Shape_CRTP<Square> {};
class Circle: public Shape_CRTP<Circle> {};

This allows obtaining copies of squares, circles or any other shapes by shapePtr->clone().

See also

  • Barton–Nackman trick

References

  1. ^ Coplien, James O. (1995, February). "Curiously Recurring Template Patterns". C++ Report: 24–27. 
  2. ^ Alexandrescu, Andrei (2001). Modern C++ Design: Generic Programming and Design Patterns Applied. Addison-Wesley. ISBN 0-201-70431-5. 
  3. ^ PN Devlog: Simulated Dynamic Binding

Wikimedia Foundation. 2010.

Игры ⚽ Нужно решить контрольную?

Look at other dictionaries:

  • Recurring — means occurring over and over and can refer to several different things: *Recurring expense, an ongoing (continual) expenditure *Curiously recurring template pattern (CRTP), a software design pattern *Recursion, a computer programming… …   Wikipedia

  • Template metaprogramming — is a metaprogramming technique in which templates are used by a compiler to generate temporary source code, which is merged by the compiler with the rest of the source code and then compiled. The output of these templates include compile time… …   Wikipedia

  • Barton-Nackman trick — is a term coined by the C++ standardization committee (ISO/IEC JTC1 SC22 WG21) to refer to an idiom introduced by John Barton and Lee Nackman as Restricted Template Expansion [cite book | last=Barton | first=John J. | coauthors=Lee R. Nackman |… …   Wikipedia

  • Jim Coplien — James O. Jim Coplien (also simply known as Cope) is a writer, lecturer, and researcher in the field of Computer Science.He has made key contributions in the areas of software design and organizational development,software debugging, and in… …   Wikipedia

  • C++ — The C++ Programming Language, written by its architect, is the seminal book on the language. Paradigm(s) Multi paradigm:[1] procedural …   Wikipedia

  • CRTP — has several meanings in computer science.* In the C++ programming language, the curiously recurring template pattern * RFC 3545, Enhanced Compressed RTP (CRTP) for Links with High Delay, Packet Loss and Reordering * RFC 2508, Compressing… …   Wikipedia

  • literature — /lit euhr euh cheuhr, choor , li treuh /, n. 1. writings in which expression and form, in connection with ideas of permanent and universal interest, are characteristic or essential features, as poetry, novels, history, biography, and essays. 2.… …   Universalium

  • performing arts — arts or skills that require public performance, as acting, singing, or dancing. [1945 50] * * * ▪ 2009 Introduction Music Classical.       The last vestiges of the Cold War seemed to thaw for a moment on Feb. 26, 2008, when the unfamiliar strains …   Universalium

  • United States — a republic in the N Western Hemisphere comprising 48 conterminous states, the District of Columbia, and Alaska in North America, and Hawaii in the N Pacific. 267,954,767; conterminous United States, 3,022,387 sq. mi. (7,827,982 sq. km); with… …   Universalium

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”