What Is the Curiously Recurring Template Pattern (Crtp)

What is the curiously recurring template pattern (CRTP)?

In short, CRTP is when a class A has a base class which is a template specialization for the class A itself. E.g.

template <class T> 
class X{...};
class A : public X<A> {...};

It is curiously recurring, isn't it? :)

Now, what does this give you? This actually gives the X template the ability to be a base class for its specializations.

For example, you could make a generic singleton class (simplified version) like this

template <class ActualClass> 
class Singleton
{
public:
static ActualClass& GetInstance()
{
if(p == nullptr)
p = new ActualClass;
return *p;
}

protected:
static ActualClass* p;
private:
Singleton(){}
Singleton(Singleton const &);
Singleton& operator = (Singleton const &);
};
template <class T>
T* Singleton<T>::p = nullptr;

Now, in order to make an arbitrary class A a singleton you should do this

class A: public Singleton<A>
{
//Rest of functionality for class A
};

So you see? The singleton template assumes that its specialization for any type X will be inherited from singleton<X> and thus will have all its (public, protected) members accessible, including the GetInstance! There are other useful uses of CRTP. For example, if you want to count all instances that currently exist for your class, but want to encapsulate this logic in a separate template (the idea for a concrete class is quite simple - have a static variable, increment in ctors, decrement in dtors). Try to do it as an exercise!

Yet another useful example, for Boost (I am not sure how they have implemented it, but CRTP will do too).
Imagine you want to provide only operator < for your classes but automatically operator == for them!

you could do it like this:

template<class Derived>
class Equality
{
};

template <class Derived>
bool operator == (Equality<Derived> const& op1, Equality<Derived> const & op2)
{
Derived const& d1 = static_cast<Derived const&>(op1);//you assume this works
//because you know that the dynamic type will actually be your template parameter.
//wonderful, isn't it?
Derived const& d2 = static_cast<Derived const&>(op2);
return !(d1 < d2) && !(d2 < d1);//assuming derived has operator <
}

Now you can use it like this

struct Apple:public Equality<Apple> 
{
int size;
};

bool operator < (Apple const & a1, Apple const& a2)
{
return a1.size < a2.size;
}

Now, you haven't provided explicitly operator == for Apple? But you have it! You can write

int main()
{
Apple a1;
Apple a2;

a1.size = 10;
a2.size = 10;
if(a1 == a2) //the compiler won't complain!
{
}
}

This could seem that you would write less if you just wrote operator == for Apple, but imagine that the Equality template would provide not only == but >, >=, <= etc. And you could use these definitions for multiple classes, reusing the code!

CRTP is a wonderful thing :) HTH

why Curiously Recurring Template Pattern (CRTP) works

Recursively-defined types aren't unusual: a linked list is recursive, too. It works because at one point in the cycle you don't need the type to be complete, you only need to know its name.

struct LinkedNode {
int data;
LinkedNode *next; // Look ma, no problem
};

In the case of CRTP, that point is here:

Base<Derived>

Instantiating Base for Derived does not require Derived to be complete, only to know that it is a class type. I.e., the following works fine:

template <class>
struct Foo { };

struct Undefined;

Foo<Undefined> myFoo;

Thus, as long as the definition of Base does not require Derived to be complete, everything just works.

C++: what is the Curiously-Recurring-Template-Pattern? and can Curiously-Recurring-Template-Pattern replace virtual functions?

Very specifically, the CRTP can be used instead of a base class with virtual functions to implement the template method pattern without virtual function call overhead.

With virtual functions, the TMP looks like this:

class ProvidesMethod {
protected:
void Method() {
// do something
Part1();
// do something else
Part2();
// do something final
}

private:
virtual void Part1() = 0;
virtual void Part2() = 0;
};

class ExposesMethod : private ProvidesMethod {
public:
using ProvidesMethod::Method;

private:
void Part1() {
// first part implementation
}
void Part2() {
// second part implementation
}
};

With the CRTP, it looks like this:

template <typename Derived>
class ProvidesMethod {
protected:
void Method() {
// do something
self().Part1();
// do something else
self().Part2();
// do something final
}

private:
Derived& self() { return *static_cast<Derived*>(this); }
const Derived& self() const { return *static_cast<const Derived*>(this); }
};

class ExposesMethod : private ProvidesMethod<ExposesMethod> {
public:
using ProvidesMethod<ExposesMethod>::Method;

private:
friend class ProvidesMethod<ExposesMethod>;
void Part1() {
// first part implementation
}
void Part2() {
// second part implementation
}
};

Is the Curiously Recurring Template Pattern (CRTP) the right solution here?

How about the other way:

template <typename ...Ts>
class Logger : private Ts...
{
public:
using Ts::write...;

void write(int x) { /*...*/ }
void write(double x) { /*...*/ }
// ...

template <typename T>
void writeLine(T x) { write(x); /*...*/ }
// ...
};

class FooWriter
{
public:
void write(FooType1 x) { /*...*/ }
void write(FooType2 x) { /*...*/ }
};
using FooLogger = Logger<FooWriter>;

And then use any of (or their aliases):

Logger<> or Logger<FooWriter> or Logger<FooWriter, BarWriter>...

A polymorphic collection of Curiously Recurring Template Pattern (CRTP) in C++?

Alf's suggestion is on target. It is easy to adapt it to your additional requirement. Define an interface with a pure virtual method:

struct BaseInterface {
virtual ~BaseInterface() {}
virtual double interface() = 0;
};

Now, your template base class can derive from the interface:

template <typename Derived>
class Base : BaseInterface {
public:
double interface(){
static_cast<Derived*>(this)->implementation();
}
};

Now, you can create a vector of pointers to the interface:

std::vector<std::shared_ptr<BaseInterface>>

Why is CRTP(curiously recursive template pattern) tries to choose another same name function of another private base class?

You should explicitly tell the compiler that base template class will implement method begin(). Inside your CI class you can do it by adding one using instruction to public section:

using GET_CONTAINRE_ITERATOR_CRTP<CI>::begin;

By default compiler makes fair suggestion that some specializations of GET_CONTAINRE_ITERATOR_CRTP temlate can be implemented without begin() method.
For futher information you can refer to Item 43 by Scott Meyers ("Effective C++")

UPD:
using GET_CONTAINRE_ITERATOR_CRTP<CI>::begin; will helps. But main reason for such behavior is in the order in which 'name lookup' and 'access checking' are done by GCC. According to the standard: The access rules (Clause 11) are considered only once name lookup and function overload resolution (if applicable) have succeeded. This leads to problem with ambiguous begin name. It is not clear while Clang behaves different.



Related Topics



Leave a reply



Submit